美文网首页
vue中的虚拟dom和双向数据绑定的结合。

vue中的虚拟dom和双向数据绑定的结合。

作者: 209bd3bc6844 | 来源:发表于2018-05-09 15:06 被阅读0次

    vue中的虚拟dom和双向数据绑定的结合。vue1.0中使用Object.defineProperty了双向数据绑定,使用dep进行订阅发布链接watcher和data的桥梁。这时候,一个data页面中用到几处就会在dep中添加几个函数更新相对应的dom。但是vue2.0中结合虚拟dom机制。所以没有所谓的temple中一个指令对应一个dom更新函数。而是一个组件只有一个更新函数为render。这个当数据变化时候,这个函数会对比前后的虚拟dom更新真正需要更新的真实dom。
    所以vue2中data的一个变量有3个地方会有对应的watcher

    1. 一个vm组件会对应一个watcher,这个watcher关注的是vm的_render方法,每个vue文件的template里面的内容都会被编译成一个_render方法,
      并且里面用到的属性或者computed都会转化成_vm.name 或者_vm.infoName 的代理形式,具体的转化过程在dep里面说到

    2. computed对象里面的每个属性,都有一个对应的watcher,如上例:infoName,infoSex都会有一个对应的watcher,并且生成的watcher的lazy为true,
      即它们都是懒更新的,只有里面用到的相关数据出现变化的时候,这个watcher才会执行getter方法

    3. watch对象里面的每个属性,都有一个对应的watcher,如上例:sex,name,"resultObj.allInfo"都会有一个对应的watcher

    我发现vue2中 对于页面渲染只会 new 一个 Watcher。因为每个Watcher的回调函数都是一样的触发render。在render的时候会遍历data触发所有的get。所有每个data的值的Watcher都是这个Watcher。更新的时候,Watcher的id一样则只更新一个,每个computed或者watch的key都会 new 一个 Watcher。这时候再执行相对应的value,就会触发相应的data的get。对应的data对push刚刚new 的这个 Watcher。

    vue2中data的watcher是如何push到对应的dep中的呢?
    vue2 中

    1. 首先会生成render函数
    2. 执行$mount函数,函数内简易关键代码如下
    var updateComponent = function () {
          vm._update(vm._render(), hydrating);
    };
    new Watcher(vm, updateComponent, noop, null, true /* isRenderWatcher */);
    
    
    function Watcher (vm,
      expOrFn,
      cb,
    ) {
    if (typeof expOrFn === 'function') { // expOrFn就为 updateComponent
        debugger
        this.getter = expOrFn;
      } else {
        this.getter = parsePath(expOrFn);
        if (!this.getter) {
          this.getter = function () {};
        }
      }
      this.value = this.lazy // computed 的lazy 才会为true。
        ? undefined
        : this.get(); // 如下段代码
      };
    }
    
    
    Watcher.prototype.get = function get () {
      pushTarget(this); // Dep.target = this;
      var value;
      var vm = this.vm;
      try {
        value = this.getter.call(vm, vm); // 执行了vm._update(vm._render(), hydrating); 
      } catch (e) {
       
      } finally {
        popTarget();// Dep.target = null;
      }
      return value
    };
    

    this.getter.call(vm, vm)触发了vm._update(vm._render(), hydrating);所以触发所有的data的get属性,所以所有的data属性都在此时添加了依赖并且是一样的依赖。

    Vue2.0 源码阅读:模板渲染
    Vue2.0 源码阅读:响应式原理

    相关文章

      网友评论

          本文标题:vue中的虚拟dom和双向数据绑定的结合。

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