vue-Vue的watch实现原理及watch实现方式

vue--Vue的watch实现原理及watch实现方式

f4MxnH7B6EZPpemiYPFDB7QTEJWN5KT2.png

参考: https://www.jianshu.com/p/ffe50c5e3368

解释:

vm 调用 $watch 后,首先调用 observe 函数 创建 Observer 实例观察数据,Observer 又创建 Dep , Dep 用来维护订阅者。然后创建 Watcher 实例提供 update函数。一旦数据变动,就层层执行回调函数。

重点:

  1. 首先确认 watch是一个对象,一定要当成对象来用。 对象就有键,有值。
  2. 对于组件选项外定义的监听函数,需要手动调用unWatch()函数进行注销 // ???喵喵
  3. watch这个特性,是针对当前组件中的初始值来进行判断的.....在初始化的时候,这个data_list已经被修改了,此时watch已经被触发。
var vm = new Vue({
  data: {
    a: 1,
    b: 2
  },
  watch: {
    a: function (val, oldVal) {
      console.log('new: %s, old: %s', val, oldVal)
    },
    // 方法名
    b: 'someMethod',
    // 选项的对象
    c: {
      handler: function (val, oldVal) { /* ... */ }, 
      deep: true,// 是否深入监听。(一般监听时是不能监听到对象属性值的变化的,数组的值变化可以听到。)
      immediate: true // 设置之后  是否以当前的初始值执行handler的函数
    }
  }
})

手动使用$watch设置初始值和注销watch

我们在初始化的时候,这个data_list已经被修改了,此时watch已经被触发。解决方法如下:

created: function() {
    axios.get(url).then(function(response){
        vm.data_list = response.data
    }
    // 这样watch的初始值就不再是原来的空数组了,而是我们赋值之后的data_list了
    this.$watch('data_list', function(){this.do_not_save = true}, {deep: true})
}

但是,如果我们使用下面这样的方式写 watch,那么就要手动注销了,这种注销其实也很简单

const unWatch = app.$watch('text', (newVal, oldVal) => {
 console.log(`${newVal} : ${oldVal}`);
})
unWatch(); // 手动注销watch

替代deep使用的节省性能开销方案

deep的意思就是深入观察,监听器会一层层的往下遍历,给对象的所有属性都加上这个监听器,但是这样性能开销就会非常大了,任何修改obj里面任何一个属性都会触发这个监听器里的 handler。

优化,我们可以是使用字符串形式监听。

watch: {
 'obj.a': {
    handler(newName, oldName) {
 console.log('obj.a changed');
    },
 immediate: true,
 // deep: true
  }
} 

你可能感兴趣的:(vue-Vue的watch实现原理及watch实现方式)