实现方式
实现双向绑定大致有以下几种方式
脏值检查
通过脏值检测的方式比对数据是否有变更,来决定是否更新视图.发布者-订阅者模式
使用自定义属性对DOM元素指明绑定对象,所有绑定的D元素和对象会”订阅”一个发布者。如果对象或者元素被侦测到发生了变化,将代理事件到发布者-订阅者模式,会将变化传播给绑定的对象和元素上。数据劫持
劫持各个属性的getter/setter,在数据变动时触发相应的监听回调。
主流框架中,Angular.js的双向绑定采用的是脏值检查方式,Vue.js则使用了发布者-订阅者模式 + 数据劫持的方式。
vue的双向绑定
原理
实现原理如下图(这张图真是太棒啦~~~)

数据监听器Observer对数据对象的属性进行监听,指令解析器Compile对元素节点的指令进行扫描和解析,根据指令模板替换,以及绑定相应的更新函数。
Watcher为订阅者,是连接Observer和Compile的桥梁,能够订阅并收到每个属性变动的通知,执行指令绑定的相应回调函数,从而更新视图。
实现逻辑
检测数据
在Observer中使用Object.defineProperty
方法定义data上的数据,实现数据劫持。
在这个过程中,需要为每个属性节点建立一个发布者,这个发布者是针对对应的属性节点以及其后代属性的。
编译模板
首先通过通过document.createDocumentFragment
方法创建文档碎片来获取模板。
之后遍历每个dom节点,使用正则匹配判断出节点中需要编译的文本,将其跟data上的数据进行匹配,并创建一个订阅者将其加入到相应的发布者中。
发布-订阅
Watcher订阅者自身有一个update()方法,待属性变动接收到通知时,能调用自身的update()方法,并触发Compile中绑定的回调。
参考
- 邓木琴居然被盗用了 — 剖析Vue原理&实现双向绑定MVVM