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

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

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

关于上一篇的几点疑问其实在看源码的过程中已经看明白了,但是回过头来发现又容易忘了,这也是我决定写几篇文章记录一下的原因。

数组的依赖收集:

 我们都知道vue中,直接改变一个数组(比如arr[1] = 2)是不会触发页面的更新的,必须调用数组的方法:arr.splice(1,1,2)才可以。
 简单说一下vue的实现:其实我们调用的splice方法并不是数组原生的方法,当observer(data)时,如果data是一个数组,那么此时就用事先定义的七个方法(push,pop,shift,unshift,sort,reverse,splice)替换掉原来数组上的方法。

  /*Observer Array*/
  var initArrayMethod = function (arr) {
    var arrayProto = Array.prototype
    // 复制原生数组原型上的方法,并替换掉其中的7个
    var arrayMethods = Object.create(arrayProto)
    ;['push', 'pop', 'shift', 'unshift', 'splice', 'sort', 'reverse'].forEach(function(method) {
      var origin = arrayMethods[method]
      arrayMethods[method] = function () {
        // 保存原生数组调用的结果
        var result = origin.apply(this, arguments)
        // 这里就是调用被观测的属性上的dep(__ob__)
        this.__ob__.dep.notify())
        return result
      }
    })
    arr.__proto__ = arrayMethods
  }

 什么时候收集的依赖呢,代码戳这里:childOb
 上面的代码中,this.ob.dep.notify()就是为什么需要在被观测的对象中也维护一个dep实例了(ob),对象上的ob主要用在这两个地方:一个就是调用数组方法之后触发订阅者回调,另一个就是vue中调用set,del方法时触发订阅者。
 对比源码可以发现,比上面的的代码要多一些,那么有什么不同呢?其实主要是这一行代码:

if (inserted) ob.observeArray(inserted)

ob.observeArray()是对数组中数据进行observe,主要是对数组嵌套对象,数组嵌套数组这种情况进行依赖收集,在这里就是对push,unshift,splice这三个有插入新的数据的方法对新插入的数据observe。
包括在Observer类中,为了使代码简便,在这里我暂时都没对数组嵌套对象的情况进行处理

深观测一个对象:

 watch方法的options中,有个deep参数,设置为true的时候,就可以深观测一个对象,其实原理非常简单,就是在依赖收集的时候遍历对象的每一个属性,触发每一个属性的getter,那么每个属性都会被依赖收集
 经过上面的处理,现在我们的vue依赖收集多了这些功能:

    var app = new Vue({
      data: function () {
        return {
          a: 1,
          b: {
            c: 2
          },
          arr: [1,2,3]
        }
      }
    })
    app.$watch('a', function () {
      console.log('a is change')
    })
    app.$watch('arr', function () {
      console.log('arr is change')
    })
    app.$watch('b', function () {
      console.log('b is change')
    }, {deep: true})
    var test = app.arr.splice(0,1,11)
    app.b.c = 3

返回结果为:

arr is change
b is change

附上本文的完整代码:附件

相关文章

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

    关于上一篇的几点疑问其实在看源码的过程中已经看明白了,但是回过头来发现又容易忘了,这也是我决定写几篇文章记录一下的...

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

    最近闲来在比较深入的学习vue的源码,受益匪浅,在这边记录一些心得,顺便给自己定个小目标--自己实现一个简单的vu...

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

    watch一个Computed属性:  其实了解完前面的依赖收集原理之后,watch一个computed属性和da...

  • vue源码调试

    1.下载vue源码的2.6.12版本的vue源码 2.源码下载好了以后,下载依赖 npm install3.依赖安...

  • Vue源码原理--依赖收集

    为何要进行依赖收集 先看下面这段代码 按照之前的文章响应式原理中的方法绑定则会出现一个问题---text3在实际模...

  • vue源码解读--依赖收集

    经过上一节(响应式的创建过程[https://www.jianshu.com/p/aa6a6c3eaeb2])分析...

  • Vue源码实现--依赖收集与页面渲染

     首先,给Watcher对象做点改动:  可以看到,在每次Watcher.run执行的时候,都会执行this.ge...

  • Vue实例简单实现

    简单实现vue框架实例,实现的目的主要看下几个知识点如何进行的: Vue工作机制 Vue响应式的原理 依赖收集与追...

  • 双向绑定的处理方式

    2019-03-11-14:21:于公司 实现Vue对数组的依赖收集和通知更新 实现Vue的数据双向绑定有3大核心...

  • 从vue注意事项到vue源码

    这几天重新看vue文档想到了vue源码中的实现,从这些地方去读源码也是一个好办法 Vue.js的响应式原理依赖于O...

网友评论

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

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