根据这张图进行总结

在组件实例初始化阶段,通过 observe() 方法对 data 对象进行递归遍历。在这个过程中,Vue 使用 Object.defineProperty() 为data 中的每个属性定义 getter 和 setter 来拦截对象属性的“读取“操作和“写入”操作。
Vue 的依赖追踪是通过 Watcher 和 Dep 协同完成的。其中,每个响应式属性背后都对应一个 Dep 对象,负责收集依赖(即 Watcher)并在数据变更时通知更新。
在组件挂载阶段,Vue 会自动创建一个渲染 Watcher。该 Watcher 会执行组件的 render 函数,并在执行过程中读取模板中所用到的响应式数据。这些数据的读取会触发它们的 getter,从而使当前正在运行的 Watcher(即渲染 Watcher)被 Dep 收集为依赖。
这个过程叫做 依赖收集(Dependency Collection)。大概的过程是:
- Watcher 在评估表达式(执行它所监听的函数或访问的数据)或渲染函数之前,把自身赋值给 Dep.target;
- 当访问响应式属性时,触发其 getter;
- 在 getter 中调用 dep.depend(),把当前 Dep.target(Watcher)添加到依赖列表中;
- 当属性变化时,setter 被触发,Dep 会通过 dep.notify() 通知所有依赖该属性的 Watcher 执行更新逻辑。
Vue 中的 Watcher 有三种类型:
- 渲染 Watcher:用于渲染视图;
- 计算属性 Watcher:用于计算属性的缓存与依赖追踪;
- 侦听器 Watcher:用于执行 watch 回调函数。
总结:
在 Vue 的响应式系统中,Observer 负责劫持数据,Dep 负责依赖管理,而 Watcher 是响应式更新的执行者。组件挂载时创建渲染 Watcher,读取数据触发 getter,完成依赖收集。数据变更时,依赖该数据的 Watcher 会被通知更新,从而驱动视图响应式变化。
| 组件 | 关键词 | 作用 |
|---|---|---|
| Observer | 劫持 | 将数据变成响应式 |
| Dep | 收集依赖 | 保存 Watcher 列表 |
| Watcher | 更新逻辑 | 数据变了就执行 |
| Compile | 模板解析 | 把模板变成 Watcher |
| View | 自动更新 | Watcher 通知它变化 |