vue2源码学习 (10) 响应式原理-8.响应式逻辑梳理

29 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第 14 天,点击查看活动详情

10.响应式原理-8.响应式逻辑梳理

start

  • 其实写到这里,整个响应式原理基本是梳理完毕了。
  • 在回过头,整体捋一捋 响应式相关的逻辑。

官方的说明

看一看官方文档对响应式原理的说明

官方文档对响应式原理的配图 data.png

image.png

官网的解释:

当你把一个普通的 JavaScript 对象传入 Vue 实例作为 data 选项,Vue 将遍历此对象所有的 property,并使用 Object.defineProperty 把这些 property 全部转为 getter/setter。

这些 getter/setter 对用户来说是不可见的,但是在内部它们让 Vue 能够追踪依赖,在 property 被访问和修改时通知变更。

每个组件实例都对应一个 watcher 实例,它会在组件渲染的过程中把“接触”过的数据 property 记录为依赖。之后当依赖项的 setter 触发时,会通知 watcher,从而使它关联的组件重新渲染。

我的理解:

  1. 对我们传入的 data 做处理,遍历每一个属性,使用 object.defineProperty 定义这些属性的 get set;
  2. 当渲染的时候,会 new Watcher
  3. 调用 render 函数进行渲染,渲染的过程中,会接触数据,从而触发数据的 get。
  4. 触发 get, 会在当前函数的闭包中 存储一个 dep。 dep 存储当前 watcher,watcher 中存储所有的相关 dep。 (收集依赖)
  5. 修改数据的时候,触发 set,触发 dep 的 notify。触发 dep 上存储的所有 watcher 的 update 方法。
  6. 异步队列,缓冲在同一事件循环中发生的所有数据变更。
  7. 最终结果就是触发 watcher 的 this.get() 方法, 从而触发重新渲染。

说说我理解的几个关键词

  1. 数据劫持
  • 在访问或者修改对象的某个属性时,通过一段代码拦截这个行为,进行额外操作或者修改返回结果。
  • 在 javascript 中,Object.defineProperty和ES6的proxy都能实现数据劫持。
  • vue@2 是借助的Object.defineProperty
  1. 依赖收集 收集有哪些 ”观察者“ 依赖了我们这个数据。

  2. 观察者模式 观察者模式定义了对象间的一种一对多的依赖关系,当 “目标对象” 的状态发生改变时,所有依赖于它的 “观察者对象” 都将得到通知,并自动更新。

    例如 dep 可以理解为 “目标对象” watcher 可以理解为 “观察者对象”

  3. 发布订阅

    • 发布订阅模式,和观察者模式很相似。
    • 但是在这两个对象之间多了一个事件通道(Event Channel)作为中间过渡,目标对象发生了变化,不直接通知观察者,而是通过事件通道去通知观察者做更新,因此观察者也只需要订阅事件通道的消息即可。

      例如:vue 中的事件总线

end

本文就整理了一下我理解的 响应式逻辑梳理