Vue的实现原理 — 个人总结

1、双向绑定简单原理

双向绑定是在单向绑定的基础上,给可输入元素添加了 change(input)事件来动态修改 model 和 view,常见的实现数据绑定方法:发布者-订阅者模式、脏值检查、数据劫持。
发布者 - 订阅者模式:发布者 - 订阅者模式和观察者模式的区别就在于前者多了一个事件调度中心。观察者模式定义了一种一对多的关系,让多个观察者同时监听同一个数据对象主体,当对象主体发生变化的时候就会通知所有观察者对象。它由两类对象组成观察者和数据主体,主体负责发布事件,观察者通过订阅事件来观察主体。
从下图中可以看出,观察者模式中观察者和目标直接进行交互,而发布订阅模式中统一由调度中心进行处理,订阅者和发布者互不干扰。这样一方面实现了解耦,还有就是可以实现更细粒度的一些控制。比如发布者发布了很多消息,但是不想所有的订阅者都接收到,就可以在调度中心做一些处理,类似于权限控制之类的。还可以做一些节流操作。
Vue的实现原理 — 个人总结
脏值检查: 就是通过检查哪些值发生了变化来更新视图,最简单的方式就是通过轮询的方法来实现,也可以在调用了某些特定的方法后进行脏值检查,比如DOM事件,譬如用户输入文本,点击按钮等。( ng-click )、XHR响应事件 ( $http )、浏览器Location变更事件 ( $location )、Timer事件( $timeout , $interval )、执行 $digest() 或 $apply()。
数据劫持:在 Vue 中就是通过 Object.definePrototype() 来劫持对象属性的 getter 和 setter ,在数据变动的时候发布消息给订阅者,并触发相应的更新回调。
要实现 MVVM 的双向绑定要实现以下几点,1、实现一个数据监听器 Observer ,进行数据劫持,当数据对象属性发生变化时,要拿到最新的值并通知订阅者。2、实现一个指令编译器 Compile,遍历DOM,对每个节点的指令进行扫描和解析,根据指令模板替换数据,已经绑定对应的更新函数。3、实现一个订阅者 Watcher, 作为连接 Observer 和 Compile 之间的桥梁,能够订阅并收到每个属性变动的通知,执行指令绑定的相关回调函数,从而更新视图。4、MVVM 入口函数,整合以上三者。

1、当 Observer 监听到数据的变化并拿到最新数据时候,怎么通知订阅者:这时候需要实现一个 消息订阅器(Dep 一个类),这个类维护了一个数组,这个数组是 所有订阅者 的集合,当监听到数据的变化时候(在set方法内写),调用这个类里面的 notify 方法,这个方法遍历了数组(所有订阅者),触发了订阅者的 update 方法,来达到更新视图的效果。
2、那么 Watcher 就是订阅者,怎么往订阅器添加订阅者?想通过dep添加订阅者,就必须要在闭包内操作,所以我们可以在 getter里面动手脚,具体就不展开说了,因为还不是很懂。在 Watcher 中记得要实现一个 update 方法,并触发 Complie 中的回调,双向绑定就实现了。

Vue的实现原理 — 个人总结