美文网首页
Vue源码实现--依赖收集(3)

Vue源码实现--依赖收集(3)

作者: 勤奋的大鱼 | 来源:发表于2018-05-27 16:30 被阅读0次

    watch一个Computed属性:

     其实了解完前面的依赖收集原理之后,watch一个computed属性和data属性并没有什么区别,就是代理computed属性到vm实例上去,那么在依赖收集的时候computed中包含的属性也会被收集到,代码如下:

      // 初始化computed
      function initComputed (vm) {
        var computed = vm._computed = vm.$options.computed
        var keys = Object.keys(computed)
        var i = keys.length
        while (i--) {
          proxyComputed(vm, keys[i])
        }
      }
      // 代理computed属性到vm实例上
      function proxyComputed (vm, key) {
        Object.defineProperty(vm, key, {
          configurable: true,
          enumerable: true,
          get: function () {
            return vm._computed[key].call(vm)
          }
        })
      }
    

    执行代码:

        var app = new Vue({
          data: function () {
            return {
              a: 1,
              b: {
                c: 2
              },
              arr: [1,2,3]
            }
          },
          computed: {
            computed1: function () {
              return this.a + this.b.c
            }
          }
        })
        app.$watch('a', function () {
          console.log('a is change')
        })
        app.$watch('computed1', function () {
          console.log('computed1 is change')
        })
        app.a = 2
    

    输出结果:

    a is change
    computed1 is change
    

    完美!但是一看vue的源码,实现起来似乎复杂好多,那么vue为什么要那样做呢,看来事情并不简单(托了下眼镜)。
    其实vue的源码中,Watcher的options中有一个lazy的参数,这个参数主要就是用在computed中的。(相关源码
    lazy watcher主要就是实现了vue中computed的缓存,我们都知道,computed计算属性的结果会被缓存,除非依赖的响应式属性变化才会重新计算。这就是靠lazy watcher实现的。
    我就试着用自己的语言说说vue中的lazy watcher的思路吧。
    1.为每个定义的computed属性创建一个内部的监视器(lazy Watcher实例),保存在vm._computedWatchers中,lazy Watcher的dirty属性为默认true,数据为脏,因为定义时不去计算watcher的值,首次访问时才会去计算并收集此watcher到computed相关属性的dep中。
    2.代理computed属性到vm实例,在代理属性的getter中,若数据为脏,则调用lazyWatcher的evaluate计算最新的数据,并设置dirty为false。若数据不为脏,则直接返回lazyWatcher的value。
    3.computed相关的属性更新时候,会触发执行lazyWatcher的update方法;若是lazyWatcher,则在update方法中只会把watcher的dirty设置为true,等下次引用该watcher的时候就会按上述步骤重新计算值

    相关文章

      网友评论

          本文标题:Vue源码实现--依赖收集(3)

          本文链接:https://www.haomeiwen.com/subject/cofazxtx.html