vue3 watch监视详解
watch监视
一 :watch监视{ref}定义的基本类型结构
<template><div class="person"><h1>情况一:watch监视{ref}定义的基本类型结构</h1><h1>当前的和为{{ sum }}</h1><button @click="changeSum">点我sum+1</button></div>
</template><script lang="ts" setup name="Person">import {ref,watch} from 'vue'let sum=ref(0)function changeSum(){sum.value +=1;}//监视情况一:watch监视{ref}定义的基本类型结构//当新的值大于等于8的时候停止监视const stopWatch=watch(sum,(newValue,oldValue)=>{console.log('sum变化了一下',newValue,oldValue)if(newValue>=8){stopWatch()}})
</script><style>.person{background-color: rebeccapurple;box-shadow: 0 0 10px;padding: 20px;border-radius: 10px;}button{margin: 0 6px;}
</style>
点击按钮之后 价格加一 watch监视sum 在控制台打印了新的值和旧的值
当新的值大于等于8的时候停止监视
二 :watch监视{ref}定义的对象类型结构
- watch的第一个参数:被监视的数据
- watch的第二个参数:回调函数
- watch的第三个参数:监视配置(deep,immediade等等)
<template><div class="person"><h1>情况二:watch监视{ref}定义的【对象类型】结构</h1><h2>汽车名字:{{ car.name }}</h2><h2>汽车价格:{{ car.price }}</h2><button @click="changeName">修改汽车名字</button><button @click="changePrice">修改汽车价格</button><button @click="changeCar">修改汽车</button></div>
</template><script lang="ts" setup name="Person">import {ref,watch} from 'vue'let car=ref({name:'兰博基尼',price:1000000})function changeName(){car.value.name+='6'}function changePrice(){car.value.price+=10000}function changeCar(){car.value ={name:"宝马",price:300000}}//监视【ref】定义的【对象类型】数据,监视的是对象的地址值watch(car,(newValue,oldValue)=>{console.log('car改变了',newValue,oldValue)})
</script><style>.person{background-color: rebeccapurple;box-shadow: 0 0 10px;padding: 20px;border-radius: 10px;}button{margin: 0 6px;}
</style>
在这里修改汽车名字 和修改汽车价格 控制台都不会打印最新的值和旧的值 是因为监视的是对象的地址值
若想监视对象内部属性的变化的话,需要手动开启深度监视
<template><div class="person"><h1>情况二:watch监视{ref}定义的【对象类型】结构</h1><h2>汽车名字:{{ car.name }}</h2><h2>汽车价格:{{ car.price }}</h2><button @click="changeName">修改汽车名字</button><button @click="changePrice">修改汽车价格</button><button @click="changeCar">修改汽车</button></div>
</template><script lang="ts" setup name="Person">import {ref,watch} from 'vue'let car=ref({name:'兰博基尼',price:1000000})function changeName(){car.value.name+='6'}function changePrice(){car.value.price+=10000}function changeCar(){car.value ={name:"宝马",price:300000}}//监视【ref】定义的【对象类型】数据,监视的是对象的地址值watch(car,(newValue,oldValue)=>{console.log('car改变了',newValue,oldValue)},{deep:true})
</script><style>.person{background-color: rebeccapurple;box-shadow: 0 0 10px;padding: 20px;border-radius: 10px;}button{margin: 0 6px;}
</style>
这个时候对象内部属性发生改变了 那么他监视也会打印出新的值和旧的值
三:监视{reactive}定义的【对象类型】结构
监视【reactive】定义的【对象类型】数据,且默认开启深度监视
<template><div class="person"><h1>情况三:监视{reactive}定义的【对象类型】结构</h1><h2>汽车名字:{{ car.name }}</h2><h2>汽车价格:{{ car.price }}</h2><button @click="changeName">修改汽车名字</button><button @click="changePrice">修改汽车价格</button><button @click="changeCar">修改汽车</button></div>
</template><script lang="ts" setup name="Person">import {reactive,watch} from 'vue'let car=reactive({name:'兰博基尼',price:1000000})function changeName(){car.name+='6'}function changePrice(){car.price+=10000}function changeCar(){Object.assign(car,{name:"宝马",price:300000})}//监视【reactive】定义的【对象类型】数据,且默认开启深度监视watch(car,(newValue,oldValue)=>{console.log('car改变了',newValue,oldValue) })
</script><style>.person{background-color: rebeccapurple;box-shadow: 0 0 10px;padding: 20px;border-radius: 10px;}button{margin: 0 6px;}
</style>
当点击修改汽车名字 或修改汽车价格 或 修改汽车时 他都监视到了
情况四:监视{reactive}定义的【对象类型】结构的某一个属性
- 若该属性值不是【对象类型】,需要写成函数形式。
<template><div class="person"><h1>情况四:监视{reactive}定义的【对象类型】结构的某一个属性的时候</h1><h2>汽车品牌:{{ car.name }}</h2><h2>汽车价格:{{ car.price }}</h2><h2>汽车样式:{{ car.design.first }} ,{{ car.design.second }}</h2><button @click="changeName">修改汽车品牌</button><button @click="changePrice">修改汽车价格</button><button @click="changeFirst">修改汽车样式一</button><button @click="changeSecond">修改汽车样式二</button><button @click="changeDesign">修改整个汽车样式</button></div>
</template><script lang="ts" setup name="Person">import {reactive,watch} from 'vue'let car=reactive({name:'奔驰',price:300000,design:{first:'梅赛德斯',second:'E300'}})function changeName(){car.name+='6'}function changePrice(){car.price+=10000}function changeFirst(){car.design.first='奔驰C260l'}function changeSecond(){car.design.second='奔驰A'}function changeDesign(){car.design={first:'奔驰GLS',second:'奔驰EQ'}}//假如我只想监视cat.namewatch(()=>{return car.name},(newValue,oldValue)=>{console.log('car.name改变了',newValue,oldValue)})
</script><style>.person{background-color: rebeccapurple;box-shadow: 0 0 10px;padding: 20px;border-radius: 10px;}button{margin: 0 6px;}
</style>
假如我修改汽车价格 修改汽车样式一 修改汽车样式二 修改整个汽车样式 都不会监视 因为我只监视了car.name 只有car.name 发生了改变的时候 控制台才会输出新的值 和旧的值
2. 若该属性值依然是【对象类型】,可直接编,也可写成函数,不过建议写成函数。
假设我想只监视整个汽车样式修改
<template><div class="person"><h1>情况四:监视{reactive}定义的【对象类型】结构的某一个属性的时候</h1><h2>汽车品牌:{{ car.name }}</h2><h2>汽车价格:{{ car.price }}</h2><h2>汽车样式:{{ car.design.first }} ,{{ car.design.second }}</h2><button @click="changeName">修改汽车品牌</button><button @click="changePrice">修改汽车价格</button><button @click="changeFirst">修改汽车样式一</button><button @click="changeSecond">修改汽车样式二</button><button @click="changeDesign">修改整个汽车样式</button></div>
</template><script lang="ts" setup name="Person">import {reactive,watch} from 'vue'let car=reactive({name:'奔驰',price:300000,design:{first:'梅赛德斯',second:'E300'}})function changeName(){car.name+='6'}function changePrice(){car.price+=10000}function changeFirst(){car.design.first='奔驰C260l'}function changeSecond(){car.design.second='奔驰A'}function changeDesign(){car.design={first:'奔驰GLS',second:'奔驰EQ'}}// //假如我只想监视cat.name// watch(()=>{return car.name},(newValue,oldValue)=>{// console.log('car.name改变了',newValue,oldValue)// })//假如我只想监视cat.designwatch(()=>car.design,(newValue,oldValue)=>{console.log('car.name改变了',newValue,oldValue)},{deep:true})
</script><style>.person{background-color: rebeccapurple;box-shadow: 0 0 10px;padding: 20px;border-radius: 10px;}button{margin: 0 6px;}
</style>
当我点击修改汽车品牌 或修改汽车价格 他并没有监视 , 因为我只监视修改汽车样式 不论是修改汽车样式一 还是 修改汽车样式二 或者是修改整个汽车样式 他都监视到了
情况五:监视上述的多个数据
<template><div class="person"><h1>情况五:监视上述的多个数据</h1><h2>汽车品牌:{{ car.name }}</h2><h2>汽车价格:{{ car.price }}</h2><h2>汽车样式:{{ car.design.first }} ,{{ car.design.second }}</h2><button @click="changeName">修改汽车品牌</button><button @click="changePrice">修改汽车价格</button><button @click="changeFirst">修改汽车样式一</button><button @click="changeSecond">修改汽车样式二</button><button @click="changeDesign">修改整个汽车样式</button></div>
</template><script lang="ts" setup name="Person">import {reactive,watch} from 'vue'let car=reactive({name:'奔驰',price:300000,design:{first:'梅赛德斯',second:'E300'}})function changeName(){car.name+='6'}function changePrice(){car.price+=10000}function changeFirst(){car.design.first='奔驰C260l'}function changeSecond(){car.design.second='奔驰A'}function changeDesign(){car.design={first:'奔驰GLS',second:'奔驰EQ'}}//监视 :情况5:监视上述多个数据watch([()=>car.name,()=>car.design.first],(newValue,oldValue)=>{console.log('car.name改变了',newValue,oldValue)},{deep:true})
</script><style>.person{background-color: rebeccapurple;box-shadow: 0 0 10px;padding: 20px;border-radius: 10px;}button{margin: 0 6px;}
</style>
这时候当我修改汽车名字 和汽车第一个样式 他会打印出来新的值和旧的值
watchEffect监视
<template><div class="person"><h1>需求:若宽度达到20 或者高度达到15时 向服务器发送一个请求</h1><h2>宽度为:{{ width }}</h2><h2>高度为:{{ height }}</h2><button @click="changeWidth">点我宽加一</button><button @click="changeHeigth">点我高加一</button></div>
</template><script lang="ts" setup name="Person">import {ref,watch,watchEffect} from 'vue'let width=ref(15)let height=ref(10)function changeWidth(){width.value +=1}function changeHeigth(){height.value +=1}watchEffect(()=>{if(width.value >=20 || height.value >=15){console.log('向服务器发送请求')}})</script><style>.person{background-color: rebeccapurple;box-shadow: 0 0 10px;padding: 20px;border-radius: 10px;}button{margin: 0 6px;}
</style>
当我想要在宽度达到20 或者高度达到15时 向服务器发送一个请求 那我就用watchEffect监视