一、Vue实现双向绑定的两大机制
Vue实现数据双向绑定主要利用的就是:数据劫持和发布订阅模式。
所谓发布订阅模式就是,定义了对象间的一种一对多的关系,让多个观察者对象同时监听某一个主题对象,当一个对象发生改变时,所有依赖于它的对象都将得到通知。
所谓数据劫持,就是利用JavaScript的访问器属性,即Object.defineProperty()方法,当对对象的属性进行赋值时,Object.defineProperty就可以通过set方法劫持到数据的变化,然后通知发布者(主题对象)去通知所有观察者,观察者收到通知后,就会对视图进行更新。
如上图所示,View模板首先经过Compiler(编译器对象)进行编译,在编译的过程中,会分析模板中哪里使用到了Vue数据(Model中的数据),一旦使用到了Vue数据(Model中的数据),就会创建一个Water(观察者对象),并且将这个观察者对象添加到发布者对象的数组中,同时获取到Vue中的数据替换编译生成一个新的View视图。
在创建Vue实例的过程中,会对Vue data中的数据进行数据劫持操作,即将data上的属性都通过Object.definePropery()的方式代理到Vue实例上,当View视图或者Vue Model中发生数据变化的时候,就会被劫持,然后通知Dep发布者对象进行视图的更新,从而实现数据的双向绑定。
二、从零实现一个简易Vue
⓪ 项目初始化
// index.html
{{scholl.name}} {{scholl.age}}
let vm = new Vue({ el: "#app", data : { scholl : { name: "zf", age: 10 } } });我们使用Vue的时候,是直接new一个Vue对象,并传入一个options配置对象,里面有el和data,先简单点只配置el和data两个属性,所以vue.js中存在一个Vue类,如:
// vue.jsclass Vue { constructor(options) { this.$el = options.el; // 保存传递的el属性 this.$data = options.data; // 保存传入的data属性 } }
① 编译模板