如果说 Vue2 的响应式原理是理解存量项目和历史限制的关键,那么 Vue3 的响应式原理,就是理解现代 Vue 项目写法和组合式 API 体验的核心。很多人会感觉 Vue3 用起来“更自然”,并不是因为只是 API 换了名字,而是因为它在底层追踪模型上做了很大调整。
这一篇重点要看的是:
- 为什么 Vue3 要从
Object.defineProperty转向Proxy; ref和reactive分别适合建什么状态;computed和 effect 机制在依赖系统里承担什么角色;- 把这些原理放回项目设计时,怎样帮助你写得更稳。
Vue3 为什么要改响应式底层?
最直接的原因,是 Vue2 那套方案在对象新增属性、数组索引、深层结构追踪这些地方天生受限。Vue3 改用 Proxy 后,数据代理的粒度和能力边界都发生了变化:
- 拦截更自然;
- 对对象和数组行为更统一;
- 不再像 Vue2 那样严重依赖初始化时就把所有属性声明齐;
- 更容易支撑组合式 API 的灵活组织方式。
所以 Vue3 的进步,不只是“语法现代化”,而是底层能力和上层组织方式一起升级了。
Proxy 相比 Vue2 的优势到底是什么?
Proxy 的最大价值,不在于名字更新潮,而在于它代理的是“对象整体访问行为”,而不是像 Vue2 那样主要围绕已有属性一个个定义 getter/setter。
这会带来几个很现实的好处:
- 对新增属性和删除属性的感知更自然;
- 对数组索引变化、长度变化等场景支持更完整;
- 对响应式对象的操作模型更统一;
- 更方便围绕依赖追踪建立现代化的组合式 API 体系。
这也是为什么 Vue3 写状态时,你会明显感觉“很多 Vue2 时代要绕的坑没那么常见了”。
ref 和 reactive 到底应该怎么选?
这是 Vue3 响应式里非常高频、也最容易被写成“经验口诀”的问题。更成熟的理解应该回到状态形态上。
ref 更适合单值或需要明确包裹边界的状态
比如:
- 数字;
- 字符串;
- 布尔开关;
- 某个局部对象引用;
- 需要在组合函数之间清晰传递的值。
它的好处是边界非常明确,一看到就知道这是一份独立响应式值。
reactive 更适合结构化对象状态
比如:
- 表单模型;
- 查询参数对象;
- 多字段联动状态;
- 某个局部页面配置对象。
它更适合那些本来就天然以对象形式存在的状态。
真正重要的是状态建模
不要把 ref 和 reactive 理解成“两个随便选的写法风格”。它们背后反映的是你对状态形态的判断:这是一份单值状态,还是一份结构化状态。
computed 为什么不是“语法简写”?
很多人第一次学 computed,会觉得它只是模板里少写一点逻辑的工具。其实它的真正价值在于:把“由其他响应式状态推导出的结果”从副作用里分离出来。
也就是说,computed 适合表达:
- 某个按钮是否可点;
- 某组展示文案是否成立;
- 当前筛选条件是否完整;
- 页面是否处于某种复合状态;
- 列表是否应该显示空状态。
这类逻辑的特点是:它们本身不是副作用,只是派生结果。把这些东西写成 watch 或放进杂乱的方法里,页面会越来越难解释。
effect 机制到底在做什么?
Vue3 响应式系统的核心之一,就是“某段逻辑执行时,会记录自己依赖了哪些响应式数据;当这些依赖变化后,再把这段逻辑重新触发”。从整体上看,这就是 effect 思维。
你可以把它理解成:
- 状态访问时登记依赖;
- 状态变化时派发更新;
- 渲染、计算属性和某些响应副作用都建立在这套机制上。
这意味着 Vue3 响应式不是孤立的几个 API,而是一套围绕依赖追踪组织起来的运行体系。理解这一点后,你再看 ref、computed、watchEffect,就不会觉得它们只是互不相关的工具箱。
Vue3 响应式对组合式 API 有什么支撑?
这其实是最值得建立的整体认知。Vue3 之所以能让状态、计算、监听和逻辑组合得更自然,很大程度上就是因为响应式模型更适合被拆到函数级别组织。
也就是说,在组合式 API 里你更容易:
- 按业务能力抽出状态和逻辑;
- 在 composable 里组织请求、权限、表单、分页等局部能力;
- 保持状态和依赖边界更清楚;
- 让同类逻辑在多个组件间复用,而不是靠 mixin 那种容易冲突的方式。
所以 Vue3 响应式原理和 Composition API 不是两件分开的事,而是一体两面。
把 Vue3 响应式放回项目里,最重要的是什么?
最重要的不是记住每个 API 的用法,而是学会这套判断:
- 这份状态应该是单值还是结构化对象?
- 这是派生结果,还是副作用?
- 这段逻辑应该放组件内部,还是提取成 composable?
- 当前写法是在顺着响应式系统走,还是在和它对抗?
只要这套判断清楚,Vue3 项目就会自然很多。反过来,如果只是把 Vue2 写法机械搬过来,即便用了 Vue3,也很容易写出“新语法下的旧问题”。
最常见的几个误区
1. 把 ref 和 reactive 当成纯风格选择
本质上它们是在表达不同状态形态。
2. 本该用 computed 的派生结果,却写成 watch
这会让简单逻辑变成副作用逻辑。
3. 组合式 API 写了很多,但没有按能力拆分
最后只是把 Options API 的混乱搬进 setup。
4. 只会调用 API,不理解依赖追踪
出现状态更新异常时就会缺少解释能力。
总结
Vue3 响应式原理真正带来的,不只是写法变化,而是一套更自然的状态代理和依赖追踪模型。Proxy 让对象和数组追踪更统一,ref 与 reactive 让状态建模更清晰,computed 负责表达派生结果,而 effect 机制则支撑了整套渲染和响应更新体系。只要把这些能力放回“状态建模、派生逻辑、副作用边界、组合式组织”这条主线上理解,Vue3 的很多设计就会真正开始变得顺手。