持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第 14 天,点击查看活动详情
10.响应式原理-8.响应式逻辑梳理
start
- 其实写到这里,整个响应式原理基本是梳理完毕了。
- 在回过头,整体捋一捋 响应式相关的逻辑。
官方的说明
看一看官方文档对响应式原理的说明
官方文档对响应式原理的配图
官网的解释:
当你把一个普通的 JavaScript 对象传入 Vue 实例作为 data 选项,Vue 将遍历此对象所有的 property,并使用 Object.defineProperty 把这些 property 全部转为 getter/setter。
这些 getter/setter 对用户来说是不可见的,但是在内部它们让 Vue 能够追踪依赖,在 property 被访问和修改时通知变更。
每个组件实例都对应一个 watcher 实例,它会在组件渲染的过程中把“接触”过的数据 property 记录为依赖。之后当依赖项的 setter 触发时,会通知 watcher,从而使它关联的组件重新渲染。
我的理解:
- 对我们传入的 data 做处理,遍历每一个属性,使用
object.defineProperty
定义这些属性的get set
; - 当渲染的时候,会
new Watcher
。 - 调用 render 函数进行渲染,渲染的过程中,会
接触
数据,从而触发数据的 get。 - 触发 get, 会在当前函数的闭包中 存储一个 dep。 dep 存储当前 watcher,watcher 中存储所有的相关 dep。 (收集依赖)
- 修改数据的时候,触发 set,触发 dep 的 notify。触发 dep 上存储的所有 watcher 的 update 方法。
- 异步队列,缓冲在同一事件循环中发生的所有数据变更。
- 最终结果就是触发 watcher 的 this.get() 方法, 从而触发重新渲染。
说说我理解的几个关键词
- 数据劫持
- 在访问或者修改对象的某个属性时,通过一段代码拦截这个行为,进行额外操作或者修改返回结果。
- 在 javascript 中,
Object.defineProperty和ES6的proxy
都能实现数据劫持。 - vue@2 是借助的
Object.defineProperty
-
依赖收集 收集有哪些 ”观察者“ 依赖了我们这个数据。
-
观察者模式 观察者模式定义了对象间的一种一对多的依赖关系,当 “目标对象” 的状态发生改变时,所有依赖于它的 “观察者对象” 都将得到通知,并自动更新。
例如 dep 可以理解为 “目标对象” watcher 可以理解为 “观察者对象”
-
发布订阅
- 发布订阅模式,和观察者模式很相似。
- 但是在这两个对象之间多了一个事件通道(Event Channel)作为中间过渡,目标对象发生了变化,不直接通知观察者,而是通过事件通道去通知观察者做更新,因此观察者也只需要订阅事件通道的消息即可。
例如:vue 中的事件总线
end
本文就整理了一下我理解的 响应式逻辑梳理