← [ BACK_TO_NOTES ]

Vue响应式系统

Vue3 如何通过响应式状态驱动视图与副作用更新。

#frame #vue3 #concept #growing

[!info] related notes

Vue响应式系统

Vue 响应式系统的目标是:当状态变化时,让依赖该状态的模板、计算结果和副作用自动更新。

一句话定义

响应式不是“自动刷新页面”这么简单,而是 Vue 把“数据变化”和“依赖更新”建立成了一套可追踪的关系。

和 React 最大的直觉差异

如果你同时学 React 和 Vue,这里最值得抓住的差异是:

  • React 更强调“组件重新执行 + Hook 顺序 + 显式依赖”
  • Vue 更强调“响应式依赖收集 + 值变化驱动依赖重新计算”

所以 Vue 里很多体验会更像:

  • 你声明一个响应式来源
  • 依赖它的计算和副作用自动知道自己依赖了什么

而 React 里则更常需要你显式管理:

  • state 放哪
  • effect 依赖写什么
  • 哪些引用需要稳定

Vue3 为什么改用 Proxy

  • Vue2 主要依赖 Object.defineProperty
  • Vue3 改用 Proxy 代理整个对象
  • 这样可以更自然地监听属性新增、删除、数组变化和更复杂的数据结构

最常用的 5 个响应式 API

ref

适合表示单个响应式值,尤其是基本类型。

const count = ref(0)
count.value++

reactive

适合表示结构化对象状态。

const state = reactive({
  count: 0,
  user: { name: 'Tom' },
})

computed

用于表达派生状态,而不是重复存储结果。

watch

显式监听某个来源,适合在值变化后执行副作用。

watchEffect

自动收集依赖,适合快速声明一段响应式副作用。

如果要分别看边界和选型,继续读:

最重要的两个边界

派生值优先用 computed

如果一个值可以由其他状态推导出来,就不要再额外存一份。

副作用才用 watch / watchEffect

如果只是为了渲染结果,不要把本该用 computed 表达的逻辑塞进侦听器。

一个更体系化的理解

可以先把 Vue 响应式系统拆成三层:

  • 状态来源:ref / reactive
  • 派生结果:computed
  • 副作用响应:watch / watchEffect

这和 React 里:

  • useState
  • 渲染期派生 / useMemo
  • useEffect

在问题分层上是相似的,但运行机制不同。

ref 和 reactive 怎么选

  • 基本类型优先 ref
  • 表单对象、页面状态对象常用 reactive
  • 需要整体替换对象时,ref({}) 往往更灵活

常见误区

  • 在 JS 中忘记访问 ref.value
  • 用侦听器保存本来可以直接推导的派生结果
  • 在模板里写过重表达式,而不是提取到 computed
  • 以为响应式等于立即同步更新 DOM,忽略了批量更新与 nextTick

最短记忆方式

  • ref / reactive:保存状态
  • computed:解释状态
  • watch / watchEffect:响应状态变化后的副作用

学习检查

不看正文回答:

  1. Vue 响应式系统真正建立的是“数据变化”和什么之间的关系?
  2. ref、reactive、computed、watch、watchEffect 分别位于状态来源、派生、Effect 哪一层?
  3. 为什么可推导值优先 computed,而不是 watch 后再存一份 state?
  4. Vue3 使用 Proxy 相比 Vue2 的 defineProperty 主要改善了哪些观察边界?
  5. 为什么响应式 state 变化不等于 DOM 在当前语句后立刻同步完成更新?
  6. ref({}) 与 reactive({}) 在整体替换和访问模型上有什么差异?
  7. 给一个“筛选列表 + 请求日志 + UI 计数”场景,分别判断哪些应是 source state、computed、watch/effect。
创建于 2026/3/19 更新于 2026/9/30
Digital Biome
Access

键盘导航

j / k / ↑ / ↓
选择对象
Enter / o
打开选择
/ 或 Ctrl+K
全站搜索
i / f / 1–4
筛选当前列表
g → h / l / p / t / a
首页 / 笔记 / 项目 / 工具 / About
r → 1–9
打开所选对象的关联
u
返回上一页
Esc
关闭浮层 / 取消命令;输入框内清空文本