美文网首页
梳理Vue2.0双向绑定的实现原理

梳理Vue2.0双向绑定的实现原理

作者: 布袋猫g | 来源:发表于2017-08-21 12:30 被阅读0次

Vue.js 最显著的功能就是响应式系统,它是一个典型的 MVVM 框架,模型(Model)只是普通的 JavaScript 对象,修改它则视图(View)会自动更新。这种设计让状态管理变得非常简单而直观

Vue的MVVM模型示意图

vue-mvvm.png

Vue数据响应原理图

vue-data.png

实现MVVM通用方式

要实现mvvm的双向绑定,就必须要实现以下几点:
1、实现一个数据监听器Observer,能够对数据对象的所有属性进行监听,如有变动可拿到最新值并通知订阅者
2、实现一个指令解析器Compile,对每个元素节点的指令进行扫描和解析,根据指令模板替换数据,以及绑定相应的更新函数
3、实现一个Watcher,作为连接Observer和Compile的桥梁,能够订阅并收到每个属性变动的通知,执行指令绑定的相应回调函数,从而更新视图
4、mvvm入口函数,整合以上三者

整体感知virtual DOM

virtual DOM分为三个步骤:
1.createElement(): 用 JavaScript对象(虚拟树) 描述 真实DOM对象(真实树)
2.diff(oldNode, newNode) : 对比新旧两个虚拟树的区别,收集差异
3.patch() : 将差异应用到真实DOM树

有的时候 第二步 可能与 第三步 合并成一步(Vue 中的patch就是这样)

Vue的实现原理总结

  1. 首先,在实例化的过程中,把一个普通 JavaScript 对象传给 Vue 实例的 data
    选项,Vue 将遍历此对象所有的属性,并使用 Object.defineProperty 把这些属性全部转为 getter/setter。
  2. Dep 是一个依赖收集器。data 下的每一个属性都有一个唯一的 Dep 对象,在 get 中收集仅针对该属性的依赖,然后在 set 方法中触发所有收集的依赖。
  3. 在Watcher中对表达式求值,从而触发数据的get。在求值之前将当前Watch实例设置到全局,使用pushTarget(this)方法。
  4. 在get()中收集依赖,this.subs.push(sub),set的时候触发回调Dep.notify()。
  5. Compile中首先将template或el编译成render函数,render函数返回一个虚拟DOM对象(将模板转为 render 函数的时候,实际是先生成的抽象语法树(AST),再将抽象语法树转成的 render 函数)
  6. 当 vm._render 执行的时候,所依赖的变量就会被求值,并被收集为依赖。按照Vue中 watcher.js 的逻辑,当依赖的变量有变化时不仅仅回调函数被执行,实际上还要重新求值,即还要执行一遍
  7. 如果还没有 prevVnode 说明是首次渲染,直接创建真实DOM。如果已经有了 prevVnode 说明不是首次渲染,那么就采用 patch 算法进行必要的DOM操作。这就是Vue更新DOM的逻辑。
() => {
  vm._update(vm._render(), hydrating)
}
    这实际上就做到了 re-render,因为 vm._update 就是开头所说的虚拟DOM中的最后一步:patch

详细表述

图片来源: Vue2.1.7源码学习__HcySunYang

Paste_Image.png

参考资料

Vue2.1.7源码学习
Vue 源码解析:深入响应式原理
重复造轮子:从0开始实现Vue数据绑定

相关文章

网友评论

      本文标题:梳理Vue2.0双向绑定的实现原理

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