vue的双向数据绑定原理

最近在网上看了vue的双向数据绑定分析,记录一下,它的总体流程图是这样的
微信图片_20200211212857.png
image.png
当咱们这样去使用vue的时候都经历了什么vue

每次须要改变数据的时候都是this.data='xx'去修改数值,因此我就从这里下手,咱们先遍历data里的全部属性,而后经过object.defineProperty的get和set方法去监听数据的修改,这里就完成了图里的观察者对象observergit

image.png

到这咱们就能够完成数据的监听了,可是,它是怎么触发视图的更新的呢,这里要加入发布订阅模式,在数据发生变化的时候去通知全部watcher更新数值,因此要在这以前,就是在编译到视图读取值的时候把watcher加入到watcherCollector数组里github

image.png

如今开始编译HTML模版对象,先建立代码碎片,而后用js循环遍历dom节点数组

image.png

经过正则拿到的是相似people.name(由于咱们是这样用的{{people.name}})微信

image.png

读这个属性的时候就会触发observer的get函数,此时Dep.target是没有值的,因此这时候依赖还没添加成功dom

image.png

因此在读这个属性以后去new一个watcher实例函数

image.png
image.png

把expr(people.name),vm,和回调函数传进去挂载到this里,而后把this赋值给全局的Dep.target,因此这个watcher长这个样子this

image.png

由于建立watcher会去调用getOldVal这个方法,它又回去拿people.name的值因此会再次触发observer里的get函数,此时Dep.target里就是有值的,这时候依赖就添加成功了,编译到HTML里其它值的时候也相似这样,初始化完成,当修改值的时候就会触发,observer里的set函数,若是新旧值不同的时候就会去调用notify函数,通知全部watcher更新数值,这个时候基本就串起来了spa

image.png

还有一点就是代理,数据代理实现 this.person.name = '海贼王——路飞'功能,而不是this.$data.person.name = '海贼王——路飞',也是经过object.defineProperty的get和set方法去实现的3d

image.png

具体代码地址(转):https://github.com/SUNYunZeng...

相关文章
相关标签/搜索