一文让你理解vue2 的 数据 watch

lxf2023-05-04 02:21:01

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的区别

computedwatch
定义计算一个新属性,并将该属性挂载到vue实例上是监听一个已经存在的挂载在vue实例上的数据
缓存性本质是一个惰性求值的观察者,具有缓存性只有当依赖变化后,第一次访问computed 属性,才会计算新的值数据发生变化就会调用执行函数
异步不支持❌支持✅
立即执行默认会立即执行默认不会立即执行配置 immediate = true 可立即执行
场景适合一个数据被多个数据影响适合一个数据影响多个数据

一定要注意:watch里可以异步调用,比如api请求, 而computed只能同步,不能调用后端请求

面试问题:

  1. watch 和computed区别是什么?
  2. computed里可以发起异步请求吗?
  3. watch 默认是立即执行吗?怎么默认执行?
  4. watch 深度监听对象时,newvalue 和 oldvalue 一样吗?怎么解决一样的问题
  5. 深度监听的缺点是什么 ?
  6. 什么场景下适合用watch,什么时候用computed?