一、监听ref创建的基本数据类型
watch的第一个参数直接写需要监听的数据名即可,监听的是其值的变化
js
<div>
<h1>情况一:监视【ref】定义的【基本类型】数据</h1>
<h2>当前求和为:{{ sum }}</h2>
<el-button @click="changeSum">点我sum+1</el-button>
</div>
// 数据
let sum = ref(0)
// 方法
function changeSum() {
sum.value += 1
}
// 监视,情况一:监视【ref】定义的【基本类型】数据
const stopWatch = watch(sum, (newValue, oldValue) => {
console.log('sum变化了', newValue, oldValue)
if (newValue >= 10) {
stopWatch()
}
})
二、监听ref创建的对象类型
- watch监听person时,监听的是person的地址值,只有当person的引用地址发生变化时才能监听得到,当写成
Object.assign(person.value, { name: '李四', age: 90, son: { age: 5 } })
时依然监听不到 - 当开启deep: true时,无论修改person中的哪个参数,包括son对象,都能监听得到
js
<div>
<h1>情况二:监视【ref】定义的【对象类型】数据</h1>
<h2>姓名:{{ person.name }}</h2>
<h2>年龄:{{ person.age }}</h2>
<h2>儿子年龄:{{ person.son.age }}</h2>
<el-button @click="changeName">修改名字</el-button>
<el-button @click="changeAge">修改年龄</el-button>
<el-button @click="changePerson">修改整个人</el-button>
<el-button @click="changeSonAge">修改儿子年龄</el-button>
</div>
// 数据
let person = ref({
name: '张三',
age: 18,
son: { age: 5 }
})
// 方法
function changeName() {
person.value.name += '~'
}
function changeAge() {
person.value.age += 1
}
function changePerson() {
person.value = { name: '李四', age: 90, son: { age: 5 } }
}
function changeSonAge() {
person.value.son.age += 1
}
watch(
person,
(newValue, oldValue) => {
console.log('person变化了', newValue, oldValue)
},
{ deep: true }
)
三、监听reactive定义的对象类型数据,会默认开启深度监听
前面提到,如果是监听ref创建的对象类型数据,需要手动开启深度监听,而监听reactive创建的对象类型数据时,会自动开启深度监听
js
<div>
<h1>情况三:监视【reactive】定义的【对象类型】数据</h1>
<h2>姓名:{{ person.name }}</h2>
<h2>年龄:{{ person.age }}</h2>
<el-button @click="changeName">修改名字</el-button>
<el-button @click="changeAge">修改年龄</el-button>
<el-button @click="changePerson">修改整个人</el-button>
<hr />
<h2>测试:{{ obj.a.b.c }}</h2>
<el-button @click="test">修改obj.a.b.c</el-button>
</div>
// 数据
let person = reactive({ name: '张三', age: 18 })
let obj = reactive({ a: { b: { c: 666 } } })
// 方法
function changeName() {
person.name += '~'
}
function changeAge() {
person.age += 1
}
function changePerson() {
Object.assign(person, { name: '李四', age: 80 })
}
function test() {
obj.a.b.c += 888
}
// 监视,情况三:监视【reactive】定义的【对象类型】数据,且默认是开启深度监视的
watch(person, (newValue, oldValue) => {
console.log('person变化了', newValue, oldValue)
})
watch(obj, (newValue, oldValue) => {
console.log('Obj变化了', newValue, oldValue)
})
四、监听ref或reactive定义的对象类型中的某个属性
- 监听的是对象的基本类型数据,要写成函数形式
- 监听的是对象的对象类型数据,可以写成函数形式,也可以直接写
- 监听的是对象的对象类型数据,并且改变对象时改变了应用地址,例如
person.car = { ... }
,就必须要写成函数形式
js
<div>
<h1>情况四:监视【ref】或【reactive】定义的【对象类型】数据中的某个属性</h1>
<h2>姓名:{{ person.name }}</h2>
<h2>年龄:{{ person.age }}</h2>
<h2>汽车:{{ person.car.c1 }}、{{ person.car.c2 }}</h2>
<el-button @click="changeName">修改名字</el-button>
<el-button @click="changeAge">修改年龄</el-button>
<el-button @click="changeC1">修改第一台车</el-button>
<el-button @click="changeC2">修改第二台车</el-button>
<el-button @click="changeCar">修改整个车</el-button>
</div>
// 数据
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: '爱玛' }
Object.assign(person.car, { c1: '雅迪', c2: '爱玛' })
}
// 监视,情况四:监视响应式对象中的某个属性,且该属性是基本类型的,要写成函数式
watch(
() => person.name,
(newValue, oldValue) => {
console.log('person.name变化了', newValue, oldValue)
}
)
watch(
() => person.car, // 如果使用 person.car = { ... } 必须要使用函数写法;如果使用Object.assign,可以直接写person.car
(newValue, oldValue) => {
console.log('person.car变化了', newValue, oldValue)
},
{ deep: true }
)
如果需要监听多个数据,可以将2个watch合并为一个:
js
watch(
[() => person.name, () => person.car],
(newValue, oldValue) => {
console.log('person.car变化了', newValue, oldValue)
},
{ deep: true }
)
总结:
- 监听ref创建的基本数据类型,必须直接写,不可以写成函数形式
- 监听ref创建的对象数据类型,可以直接写,也可以写成函数形式,需要开启deep: true
- 监听reactive创建的对象数据类型,必须直接写,不可以写成函数形式,默认开启了deep: true
- 监听ref或reactive创建的对象类型中的某个属性,该类型为基本数据类型,必须写成函数形式
- 监听ref或reactive创建的对象类型中的某个属性,该类型为对象数据类型,可以直接写,也可以写成函数形式,需要开启deep: true。如果想要监听引用地址变化,必须写成函数形式
序号 | 情况 | 是否使用函数写法 | 是否需要手动开启深度监听 |
---|---|---|---|
1 | 监听ref创建的基本数据类型 | 否。必须直接写,不可以写成函数形式 | 否 |
2 | 监听ref创建的对象数据类型 | 皆可。可以直接写,也可以写成函数形式 | 是 |
3 | 监听reactive创建的对象数据类型 | 否。必须直接写,不可以写成函数形式 | 否。默认开启了深度监听 |
4 | 监听ref或reactive创建的对象类型中的某个属性,该类型为基本数据类型 | 是。必须写成函数形式 | 否 |
5 | 监听ref或reactive创建的对象类型中的某个属性,该类型为对象数据类型 | 皆可。可以直接写,也可以写成函数形式;如果想要监听引用地址变化,必须写成函数形式 | 是 |