快速理解VUE的响应式原理主要通过下面三点:
- 数据劫持/数据代理
- 依赖收集
- 发布订阅模式
数据劫持/数据代理
实现方式1:
核心:Object.defineProperty实现
Vue通过设定对象属性的 setter/getter 方法来监听数据的变化,通过getter进行依赖收集,而每个setter方法就是一个观察者,在数据变更的时候通知订阅者更新视图
实现方式2:
核心:Proxy实现
Proxy 是 JavaScript 2015 的一个新特性。Proxy 的代理是针对整个对象的,而不是对象的某个属性,因此不同于 Object.defineProperty 的必须遍历对象每个属性,Proxy 只需要做一层代理就可以监听同级结构下的所有属性变化,当然对于深层结构,递归还是需要进行的。此外Proxy支持代理数组的变化
依赖收集
为什么要进行依赖收集?
目的在于当数据的属性发生变化时,可以通知那些曾经使用了该数据的地方(多出地方),核心思想就是事件发布订阅模式
订阅者 Dep和观察者 Watcher ,收集依赖的如何实现的?
为什么引入订阅者Dep?
收集依赖需要为依赖找一个存储依赖的地方,为此我们创建了Dep,它用来收集依赖、删除依赖和向依赖发送消息等。
于是我们先来实现一个订阅者 Dep 类,用于解耦属性的依赖收集和派发更新操作,说得具体点,它的主要作用是用来存放 Watcher 观察者对象。我们可以把Watcher理解成一个中介的角色,数据发生变化时通知它,然后它再通知其他地方
为什么引入观察者Watcher?
当属性发生变化后,我们要通知用到数据的地方,而使用这个数据的地方有很多,而且类型还不一样,既有可能是模板,也有可能是用户写的一个watch,这时需要抽象出一个能集中处理这些情况的类。然后,我们在依赖收集阶段只收集这个封装好的类的实例进来,通知也只通知它一个,再由它负责通知其他地方
下图:深入浅出的VUE.js更加方便的理解vue响应式的原理