Vue.js 响应式系统是核心机制,它能在底层数据变化时自动更新 UI。本文档解释了 Vue 如何追踪数据属性的变化并在必要时触发重新渲染。有关组件系统的更多信息,请参阅组件系统;有关虚拟 DOM 渲染的详细信息,请参阅虚拟 DOM 实现。
Vue 的响应式系统允许声明式 UI 编程——开发者定义数据状态以及它应该如何渲染,而 Vue 会在数据变化时自动更新 DOM。这是 Vue 最显著的特性之一,也是其开发者体验的关键部分。
来源
Vue 的响应式基于两个关键机制构建:
来源
当 Vue 组件创建时,会通过以下过程建立响应式:
initData 函数。来源
Vue 的响应式系统基于观察者模式。我们来看看关键部分:
Vue 初始化时,它会遍历数据对象,并使用 defineReactive 将每个属性转换为 getter/setter 对。
来源
当组件渲染时,它会访问数据属性,这会触发 getter。getter 会记录当前活动的 watcher(通常是组件的渲染 watcher)作为依赖。
来源
当数据属性发生变化时,setter 会被触发,它会通知所有依赖于此属性的 watcher。
来源
Vue 使用 Watcher 类主要用于三个目的:
| Watcher 类型 | 创建者 | 目的 |
|---|---|---|
| 渲染 Watcher | 组件挂载 | 数据变化时更新组件视图 |
| 计算属性 Watcher | 计算属性 | 缓存并重新计算派生值 |
| 用户 Watcher | watch 选项/函数 | 数据变化时执行用户回调 |
来源
每个 Vue 组件在挂载过程中都会创建一个渲染 watcher。此 watcher 的 getter 函数是组件的渲染函数,它访问响应式数据并建立依赖。
来源
计算属性创建的是惰性 watcher,它们只在其依赖发生变化时才会重新计算。
来源
Vue 2.7 包含 Vue 3 组合式 API 响应式系统的回溯版本。这提供了创建和使用响应式状态的新方式。
| API | 目的 |
|---|---|
ref | 创建值的响应式引用 |
reactive | 创建对象的响应式代理 |
computed | 创建自动更新的计算值 |
watch | 侦听响应式源并在它们变化时运行回调 |
watchEffect | 立即运行函数并追踪依赖 |
来源
Vue 2.7 还包含 Vue 3 的 EffectScope 概念,它有助于管理响应式副作用的生命周期。
来源
以下是响应式从初始化到更新的流程:
来源
Vue 的响应式系统包含多项优化:
来源
由于 JavaScript 的限制,Vue 的响应式系统有一些局限性:
Vue.set/Vue.delete 或扩展运算符)。push、pop 等特殊方法时检测数组的变化。来源
在 Vue 2.7 中,组合式 API 的 setup 函数与现有的响应式系统集成。
来源
Vue 的响应式系统是观察者模式的强大但抽象的实现。通过透明地将数据属性转换为 getter/setter 并追踪依赖,Vue 创建了一个系统,使数据的变化能够自动反映到 UI 更新中,同时最大限度地减少了开发者的工作量。