watch 选项用于定义一个或多个观察者,它们会监视指定的数据属性的变化。当被监视的属性发生变化时,相应的处理函数会被调用,从而允许你对变化做出反应。
watch监视的五种情况:
一、监视ref定义的基本类型数据
<template>
<h1>你好person</h1>
<div class="person">
<h2>监视ref定义的基本类型数据</h2>
<h3>和:{{ sum }}</h3>
<button @click="changeSum">点我加一</button>
</div>
</template>
<script lang="ts" setup name="Person">
import {ref,watch} from 'vue'
let sum=ref(0)
function changeSum() {
//使用ref时获取数据要加.value
sum.value+=1
}
// watch监视,监视ref定义的基本类型数据
// 当sum的值大于10的时候解除监视
const stopWatch=watch(sum,(newValue,oldValue)=>{
console.log('新值',newValue,'旧值',oldValue)
if(newValue >= 10) {
//解除监视
stopWatch()
}
})
</script>
<style scoped>
.person{
background-color: bisque;
}
</style>
每次点击按钮后,控制台会显示点击前后的旧值和新值,当新值大于10时解除监视,控制台不再显示新值10以后的数据。
二、监视ref定义的对象类型数据
<template>
<h1>你好person</h1>
<div class="person">
<h2>监视ref定义的对象类型数据</h2>
<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">
import {ref,watch} from 'vue'
let person=ref({
name:'张张',
age:22
})
function changeName() {
person.value.name+='~'
}
function changeAge() {
person.value.age+=1
}
function changePerson() {
person.value={name:'张',age:30}
}
// 监视
watch(person,(newValue,oldValue)=>{
console.log('新值',newValue,'旧值',oldValue);
})
</script>
<style scoped>
.person{
background-color: bisque;
}
</style>
此时只有点击“点击修改信息”按钮时,控制台才会显示数据。
深度监视:
ref定义的【对象类型】数据:直接写数据名,监视的是对象的【地址值】,若想监视对象内部的数据,要手动开启深度监视。
// 深度监视
//watch的三个参数分别是:被监视的数据,监视的回调,配置对象(如deep、immediate)。
watch(person,(newValue,oldValue)=>{
console.log('新值',newValue,'旧值',oldValue);
},{deep:true})
此时,无论点击哪一个按钮,控制台都会显示数据。
若修改的是ref定义的对象中的属性,newValue 和 oldValue 都是新值,因为它们是同一个对象。
若修改整个ref定义的对象,newValue 是新值, oldValue 是旧值,因为不是同一个对象了。
三、监视reactive定义的对象类型数据(默认开启深度监视)
<template>
<h1>你好person</h1>
<div class="person">
<h2>监视reactive定义的对象类型数据</h2>
<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">
import {reactive,watch} from 'vue'
let person=reactive({
name:'张张',
age:22
})
function changeName() {
person.name+='~'
}
function changeAge() {
person.age+=1
}
function changePerson() {
Object.assign(person,{name:'张',age:30})
}
// 监视reactive定义的对象类型数据,默认是开启深度监视的
watch(person,(newValue,oldValue)=>{
console.log('新值',newValue,'旧值',oldValue);
})
</script>
<style scoped>
.person{
background-color: bisque;
}
</style>
监视reactive定义的对象类型数据,会默认开启深度监视,此时无论点击哪个按钮,控制台都会打印数据。
四、监视ref或reactive定义的【对象类型】数据中的某个属性
<template>
<div class="person">
<h1>情况四:监视【ref】或【reactive】定义的【对象类型】数据中的某个属性</h1>
<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">修改第一台车</button>
<button @click="changeC2">修改第二台车</button>
<button @click="changeCar">修改整个车</button>
</div>
</template>
<script lang="ts" setup name="Person">
import {reactive,watch} from 'vue'
let person = reactive({
name:'张三',
age:18,
car:{
c1:'奔驰',
c2:'宝马'
}
})
function changeName(){
person.name += '~'
}
function changeAge(){
person.age += 1
}
function changeC1(){
person.car.c1 = '奥迪'
}
function changeC2(){
person.car.c2 = '大众'
}
function changeCar(){
person.car = {c1:'雅迪',c2:'爱玛'}
}
// 监视响应式对象中的某个属性,且该属性是基本类型的,要写成函数式
/* watch(()=> person.name,(newValue,oldValue)=>{
//点击“修改名字”按钮,控制台打印出名字的新值旧值,两者相同
console.log('person.name变化了',newValue,oldValue)
}) */
// 监视响应式对象中的某个属性,且该属性是对象类型的,可以直接写,也能写函数,更推荐写函数
watch(()=>person.car,(newValue,oldValue)=>{
console.log('person.car变化了',newValue,oldValue)
},{deep:true})
</script>
<style scoped>
.person{
background-color: bisque;
}
</style>
点击“修改名字”、“修改年龄”时,页面上会响应出数据。
点击其余按钮,不仅页面上数据改变,而且控制台能打印出新值旧值数据。
五、监视上述的多个数据
<template>
<div class="person">
<h1>情况五:监视上述的多个数据</h1>
<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">修改第一台车</button>
<button @click="changeC2">修改第二台车</button>
<button @click="changeCar">修改整个车</button>
</div>
</template>
<script lang="ts" setup name="Person">
import {reactive,watch} from 'vue'
let person = reactive({
name:'张三',
age:18,
car:{
c1:'奔驰',
c2:'宝马'
}
})
function changeName(){
person.name += '~'
}
function changeAge(){
person.age += 1
}
function changeC1(){
person.car.c1 = '奥迪'
}
function changeC2(){
person.car.c2 = '大众'
}
function changeCar(){
person.car = {c1:'雅迪',c2:'爱玛'}
}
//监视响应式对象中的某个属性,且该属性是基本类型的,要写成函数式
// 监视响应式对象中的某个属性,且该属性是对象类型的,可以直接写,也能写函数
watch([()=>person.name,person.car],(newValue,oldValue)=>{
console.log('person.car变化了',newValue,oldValue)
},{deep:true})
</script>
<style scoped>
.person{
background-color: bisque;
}
</style>
从左至右依次点击各个按钮: