前言
React,Angular,Vue三大框架的火热,响应式功不可没。响应式通过数据的变更直接更新视图省去了繁杂的Dom操作。当前React主要是用虚拟Dom+diff算法来实现响应式,Vue2使用object的defineProperty和观察者模式来实现响应式。本文主要是我学习vue2响应式原理的一个记录。首先介绍下什么是响应式,接着了解下Object.defineProperty和观察者模式,最后结合官方的流程图;理解Object.defineProperty和观察者模式在vue2响应式中的应用。
什么是响应式
简单的说,就是当数据发生改变的时候,视图也会跟着改变,当视图重新渲染的时候,数据也会重新改变。这样的变化就是响应式。响应式的好处是省去了繁杂的Dom操作。用户只要专注于数据和视图的组织就好。 Vue2实现响应式是使用Object.definedProperty这个方法来劫持变量的getter和setter,并使用观察者模式来将数据的改变或者视图的改变通知给Watcher。也就是说如果要学习Vue2的响应式原理,首先得明白Object.defineProperty和观察者模式是什么。接下来先简单介绍下Object.defineProperty和观察者模式。
预备知识
Object.defineProperty
Object.defineProperty()会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象。Vue2主要利用这个方法给数据对象绑定get和set函数,实现对组件渲染(使用数据->触发getter)和修改数据(修改->触发setter)的监听。
观察者模式
观察者模式又称订阅-发布模式,是一种常见的设计模式。主要解决一个对象状态改变给其他对象通知的问题。模式的思想在生活中也很常见,比如我们喜欢看一个b站up主的视频我们不会傻等它发布,我们会关注下这个up主,当这个up主更新视频了系统会吧这个视频推到所有关注者的首页上。这就是观察者模式的主要思想。Vue2吧组件的渲染作为订阅来和数据产生一个依赖关系。在产生依赖关系之后,当数据发生变化组件就会收到数据修改的通知进行重新渲染。
Vue2实现响应式的过程
- 在组件初始化的时候,先给每一个Data属性都注册getter,setter,这个过程也叫reactive化。然后再new一个自己的Watcher对象,此时Watcher会立即调用组件的render函数去生成虚拟DOM。在调用render的时候,就会需要用到data的属性值,此时会触发getter函数,将当前的Watcher函数注册进data的观察者类里。(这就是观察者模式中的订阅,这个过程也叫依赖收集(collect as Dependency))
- 当data属性发生改变之后,它会遍历自身观察者类里所有的Watcher对象,通知(Notify)它们去重新渲染组件。(相当于观察者模式中的发布)
可以对照图一来看这个过程
参考资料
1. 最简化 VUE的响应式原理 - 知乎 (zhihu.com) 2. 观察者模式 | 菜鸟教程 (runoob.com) 3. Object.defineProperty() - JavaScript | MDN (mozilla.org) 4. . 深入响应式原理 — Vue.js (vuejs.org)
|