一文让你理解vue2 的 数据 watch
watch
定义:
- 是个对象,不是方法
- 对象的key:是需要 观察的**表达式 **
- 对象的value: 可以是个回调函数、函数名、对象(内部包含了配置的属性)
- 运行时机: vue实例会在实例化时调用$watch(), 遍历watch 对象的每一个 property
属性
key值方式
- 可以是对象名,如 person
- 也可以是字符串形式,对象深层名,如 'person.name'
deep:
- true: 深度遍历
- 缺点:消耗过大
immediate: (默认值为false)
- true: 立即执行
语法
watch: {
a: function (val, oldVal) {
console.log('new: %s, old: %s', val, oldVal)
},
// 方法名
b: 'someMethod',
// 该回调会在任何被侦听的对象的 property 改变时被调用,不论其被嵌套多深
c: {
handler: function (val, oldVal) { /* ... */ },
deep: true
},
// 该回调将会在侦听开始之后被立即调用
d: {
handler: 'someMethod',
immediate: true
},
// 你可以传入回调数组,它们会被逐一调用
e: [
'handle1',
function handle2 (val, oldVal) { /* ... */ },
{
handler: function handle3 (val, oldVal) { /* ... */ },
/* ... */
}
],
// watch vm.e.f's value: {g: 5}
'e.f': function (val, oldVal) { /* ... */ }
}
扩展
不要使用箭头函数定义watcher函数
箭头函数绑定了父级作用域的上下文,所以此时的this 不会指向vue实例,而是undefined
Vue深度监听对象时,新旧值一致
data(){
return {
person:{
name:"东方青苍"
}
}
}
watch: {
person: {
deep: true,
handler(newVal, oldVal) {
console.log(newVal.name, oldVal.name);
}
}
}
问题!!!:会发现打印的新旧值都一样
解决方案:
使用计算属性computed,深拷贝我们想要监听的对象, 然后再去watch 【computed 里的新的key (copyPerson)】
computed: {
copyPerson() {
return JSON.parse(JSON.stringify(this.person))
}
},
watch: {
copyPerson: {
deep: true,
handler(newVal, oldVal) {
console.log(newVal.name, oldVal.name);
}
}
}
watch 和computer的区别
computed | watch | |
---|---|---|
定义 | 计算一个新属性,并将该属性挂载到vue实例上 | 是监听一个已经存在的挂载在vue实例上的数据 |
缓存性 | 本质是一个惰性求值的观察者,具有缓存性只有当依赖变化后,第一次访问computed 属性,才会计算新的值 | 数据发生变化就会调用执行函数 |
异步 | 不支持❌ | 支持✅ |
立即执行 | 默认会立即执行 | 默认不会立即执行配置 immediate = true 可立即执行 |
场景 | 适合一个数据被多个数据影响 | 适合一个数据影响多个数据 |
一定要注意:watch里可以异步调用,比如api请求, 而computed只能同步,不能调用后端请求
面试问题:
- watch 和computed区别是什么?
- computed里可以发起异步请求吗?
- watch 默认是立即执行吗?怎么默认执行?
- watch 深度监听对象时,newvalue 和 oldvalue 一样吗?怎么解决一样的问题
- 深度监听的缺点是什么 ?
- 什么场景下适合用watch,什么时候用computed?
转载自:https://juejin.cn/post/7213310111623184445