《Vue3学习手记2》
今天主要学习Vue3中的数据监视:
ps: 代码中的注释写的很详细,这样更有利于理解
watch
作用: 监视数据的变化(和Vue2中watch作用一致)
特点: Vue3中的watch只能监视以下四种数据:
- ref创建定义的数据(基本类型、对象类型)
- reactive定义的数据(对象类型)
- 函数返回一个值(getter函数)
- 一个包含上述内容的数组
语法: watch接收三个参数:第一个参数是监视的对象;第二个参数是执行的回调函数(回调函数会收到两个值:新值和旧值);第三个参数是是否进行深度监视或者是否打开页面就监视
下面分情况概述:
情况一:监听ref定义的基本数据及对象数据
<template><div class="app"><!-- <h2>姓名:{{name}}</h2><h2>年龄:{{age}}</h2><button @click="changeName">点击修改姓名</button><button @click="changeAge">点击修改年龄</button> --><!-- ========================================================= --><h2>姓名:{{person.name}}</h2><h2>年龄:{{person.age}}</h2><button @click="changeName">点击修改姓名</button><button @click="changeAge">点击修改年龄</button><button @click="changeperson">点击修改全部信息</button></div>
</template><script lang="ts" setup name="Person">// 知识点一:watch监视// 首先 引入watch// watch监视的是ref定义的基本响应式数据import {ref,watch} from "vue"// 数据// const name=ref("张三")// const age=ref(18)// // 方法// function changeName(){// name.value+="~"// }// function changeAge(){// age.value++// }// watch在vue2是配置项,在vue3中是函数。// 对name进行监视// watch(name,(newValue,oldValue)=>{// console.log("name改变了",newValue,oldValue)// })// =========================================================// 知识点二:watch监视的是ref定义的对象数据const person=ref({name:"张三",age:18})function changeName(){person.value.name+="~"}function changeAge(){person.value.age++}function changeperson(){person.value={name:"李四",age:19}}// 对person进行监视,此时只能监视到整个person的变化,而不能检测到person里属性的变化// watch(person,(newValue,oldValue)=>{// console.log("person改变了",newValue,oldValue)// })// 添加第三个参数,可以检测到person中属性name和age的变化watch(person,(newValue,oldValue)=>{console.log("person改变了",newValue,oldValue)},{deep:true,immediate:true})// =========================================================// 注意:// 进行深度监视后,name和age属性可以被监视到。// 监测name和age返回的新值和旧值都是新值,因为他们是同一对象// 监测整个person对象返回的分别是新值和旧值,因为他们不是同一对象,因为整个person都被修改了</script><style>.app {background-color: #ddd;box-shadow: 0 0 10px;border-radius:10px;padding: 20px;}
</style>
情况二: 监视reactive定义的对象数据
<template><div class="app"><h2>姓名:{{person.name}}</h2><h2>年龄:{{person.age}}</h2><button @click="changeName">点击修改姓名</button><button @click="changeAge">点击修改年龄</button><button @click="changeperson">点击修改全部信息</button></div>
</template><script lang="ts" setup name="Person">// 知识点一:watch监视// 首先 引入watch// watch监视的是reactive定义的对象响应式数据import {reactive,watch} from "vue"const person=reactive({name:"张三",age:18})function changeName(){person.name+="~"}function changeAge(){person.age++}function changeperson(){Object.assign(person,{name:"李四",age:20})}// 对person进行监视,此时只能监视到整个person的变化,也能能检测到person里属性的变化(reactive对象数据,默认开启深度监视watch(person,(newValue,oldValue)=>{console.log("person改变了",newValue,oldValue)})// =========================================================// 注意:// 监测name和age返回的新值和旧值(newValue和oldValue)都是新值,因为他们是同一对象// 监测整个person对象返回的newValue和oldValue分别是新值和旧值,因为他们不是同一对象
// ========================================================= //总结: //reactive定义的对象数据和ref相同,都是对象中的属性 返回的新值和旧值都是新值,而整个person对象返回的newValue和oldValue分别是新值和旧值</script><style>.app {background-color: #ddd;box-shadow: 0 0 10px;border-radius:10px;padding: 20px;}
</style>
情况三:(函数返回一个值)监视一个getter函数
常用于监视某个属性
<template><div class="app"><h2>姓名:{{person.name}}</h2><h2>年龄:{{person.age}}</h2><h2>汽车:{{person.car.C1}}-{{ person.car.C2 }}</h2><button @click="changeName">点击修改姓名</button><button @click="changeAge">点击修改年龄</button><button @click="changeC1">点击修改C1</button><button @click="changeC2">点击修改C2</button><button @click="changecar">点击修改汽车</button></div>
</template><script lang="ts" setup name="Person">// 知识点一:watch监视// 首先 引入watch// watch监视:函数返回一个值(getter函数)import {reactive,watch} from "vue"const person=reactive({name:"张三",age:18,car:{C1:"柯尼塞格",C2:"布加迪威龙"}})function changeName(){person.name+="~"}function changeAge(){person.age++}function changeC1(){person.car.C1="奥迪"}function changeC2(){person.car.C2="大众"}function changecar(){person.car={C1:"特斯拉",C2:"小米"} //这里注意,由于car也是一个对象,所以不用用Object assign来定义}// =========================================================// 要求一:只对name属性进行监视 此时需要写成getter函数(watch可以检测到getter函数),判断该属性是不是对象类型,不是对象类型,应写成函数式// watch(()=>{return person.name},(newValue,oldValue)=>{// 可简写为:watch(()=>person.name,(newValue,oldValue)=>{console.log("name改变了",newValue,oldValue)})//要求二:只对car属性进行监视 判断该属性是不是对象类型,是对象类型,应写成函数式(推荐),也可以直接写watch(()=>person.car,(newValue,oldValue)=>{console.log("car改变了",newValue,oldValue)},{deep:true})// =========================================================// 总结:监视的是对象里的属性(注意:首先要满足是对象,不管是对象里的基本数据还是对象数据类型),最好都写成函数式,注意点:若是也需要监视对象内部,则需手动开启深度监视。</script><style>.app {background-color: #ddd;box-shadow: 0 0 10px;border-radius:10px;padding: 20px;}
</style>
情况四:监视多个数据(包含上述内容的数组)
<template><div class="app"><h2>姓名:{{person.name}}</h2><h2>年龄:{{person.age}}</h2><h2>汽车:{{person.car.C1}}-{{ person.car.C2 }}</h2><button @click="changeName">点击修改姓名</button><button @click="changeAge">点击修改年龄</button><button @click="changeC1">点击修改C1</button><button @click="changeC2">点击修改C2</button><button @click="changecar">点击修改汽车</button></div>
</template><script lang="ts" setup name="Person">// 知识点一:watch监视// 首先 引入watch// watch监视:监视上述内容的数组(多个数据)import {reactive,watch} from "vue"const person=reactive({name:"张三",age:18,car:{C1:"柯尼塞格",C2:"布加迪威龙"}})function changeName(){person.name+="~"}function changeAge(){person.age++}function changeC1(){person.car.C1="奥迪"}function changeC2(){person.car.C2="大众"}function changecar(){person.car={C1:"特斯拉",C2:"小米"} //这里注意,由于car也是一个对象,所以不用用Object assign来定义}// =========================================================// 对name属性和car对象里面的C1属性进行监视 watch([()=>person.name,()=>person.car.C1],(newValue,oldValue)=>{console.log("name和car被修改了",newValue,oldValue)},{deep:true})// 此时newValue返回的是name和car.C1返回的新值组成的数组
</script><style>.app {background-color: #ddd;box-shadow: 0 0 10px;border-radius:10px;padding: 20px;}
</style>
watchEffect
watch对比watchEffect
1.都能监听响应式数据的变化,不同的是监听数据变化的方式不同
2. watch:要明确指出监视的数据,当需要监视的数据过多时,操作麻烦
3.watchEffect:不用明确指出监视的数据(函数中用到哪些属性,那就监视哪些属性),它会自己分析。
<template><div class="app"><h2>水温:{{temp}}</h2><h2>水位:{{height}}</h2><button @click="changeTemp">点击水温+10</button><button @click="changeHeight">点击水位+10</button></div>
</template><script lang="ts" setup name="Person">// 知识点:watchEffect监视// 首先 引入watchEffectimport {ref,watch,watchEffect} from "vue"const temp=ref(0)const height=ref(10)function changeTemp(){temp.value+=10}function changeHeight(){height.value+=10}
// 要求:当水温大于60或水位大于80,向服务器发送请求
// 对水温和水位进行监视 (不是对象里的属性,可直接写)// =========================================================// 第一种写法:// watch([temp,height],()=>{ //value表示newValue,返回的是newTemp和newHeight组成的数组// // 解构// // const [newTemp,newHeight]=value// // 进行判断// if(temp.value>60 || height.value>80){// console.log("向服务器发送请求")// }// })// 第二种写法:// watch([temp,height],(value)=>{ //value表示newValue,返回的是temp和height的新值组成的数组// // 进行判断// if(value[0]>60 || value[1]>80){// console.log("向服务器发送请求")// }// })// 第三种写法:// watch([temp,height],(value)=>{ //value表示newValue,返回的是newTemp和newHeight组成的数组// // 解构// const [newTemp,newHeight]=value// // 进行判断// if(newTemp>60 || newHeight>80){// console.log("向服务器发送请求")// }// })// =========================================================// 使用watchEffect写:(直接使用,watchEffect会自己分析),适用于监视的对象足够多的情况watchEffect(()=>{if(temp.value>60 || height.value>80){console.log("向服务器发送请求")}})
</script><style>.app {background-color: #ddd;box-shadow: 0 0 10px;border-radius:10px;padding: 20px;}
</style>