VUE2数据绑定原理
简单来说,vue数据绑定的底层是使用了 ES5中的 Object.defineProperty方法,通过“发布-订阅者”模式来实现的。但要真正理解其原理,首先要了解 vue的响应式原理。
vue响应式原理
vue的响应式数据原理需要经历以下几个步骤:
- vue会遍历此 data对象中所有的属性;
- 使用 Object.defineProperty方法将这些属性全部转为 getter/setter,实现读取和写入;
- 每个组件实例中存在 watcher对象,来监听属性变化;
- 它会在组件渲染的过程中把竖向记录为依赖;
- 当依赖项的 setter被调用时,会通知 watcher重新计算,从而致使它关联的组件得以更新。
三个重要对象
而实际上,vue的数据绑定原理与 vue响应式设计原理中的三个重要对象有关:Observer、Watcher和 Dep。
这三个对象的含义分别是:
- Observer对象:vue中的数据对象在初始化的过程中会转换为 Observer对象;
- Watcher对象:将模板和 Observer对象结合在一起生成 Watcher实例,Watcher是“发布-订阅者”模式中的“订阅者”;
- Dep对象:Watcher对象和Observer对象之间的纽带,每一个 Observer对象中都有一个 Dep实例,用来储存订阅者 Watcher。
当属性发生变化时会执行主体对象 Observer的 dep.notify方法,这个方法会遍历订阅者 Watcher列表并向其发送消息,而 Watcher会执行 run方法去更新视图。
补充
模板编译过程中的指令和数据绑定都会生成 Watcher实例,实例中的 watch属性也会生成 Watcher实例。而这里的 Watcher实例则需要注意以下几点:
- 在生命周期 initState方法中将 data,prop,method,computed,watch中的数据劫持,通过 observer方法与 Object.defineProperty方法将相关对象转换为 Observer对象。
- 然后再 initRender方法中解析模板,通过 Watcher对象,Dep对象与观察者模式将模板中的指令与对象的数据建立依赖关系,使用全局对象 Dep.target实现依赖收集。
- 当数据发生变化时,setter被调用,触发 Object.defineProperty方法中的 dep.notify方法,遍历该数据依赖列表,执行器 update方法通知 Watcher进行视图更新。
同时vue中操作数据还需要注意的点是:
- vue是无法检测到对象属性的添加和删除,但是可以使用全局方法 Vue.set(或者 vm.$set实例方法);
- vue无法检测利用索引设置数组,但是可以使用全局方法 Vue.set(或者 vm.$set实例方法);
- vue无法检测直接修改数组的长度,但是可以使用数组自带方法 splice等。
这里是万物之恋,下次再见了!