Vue3响应式核心是Proxy实现的“记账+通知”机制:Proxy作为门卫追踪读写操作,Dep记录依赖,Effect执行更新;嵌套对象惰性代理,ref包装原始值以支持响应式。

Vue3 的响应式,核心就一句话:你改数据,它自动更新用到这数据的地方。背后不是魔法,是 Proxy 搭配一套精巧的“记账+通知”机制。
Proxy 是那个全程盯梢的门卫
Vue3 不再像 Vue2 那样给每个属性单独装监控(Object.defineProperty),而是直接给整个对象请了个全能门卫——Proxy。这个门卫不干别的,就两件事:
- 你一读属性(比如 state.count),门卫立刻知道:“哦,有人在看 count”,顺手记一笔:“这个人依赖 count”
- 你一改属性(比如 state.count = 5),门卫马上喊话:“count 变了!所有盯着它的人都来干活!”
这个门卫还能盯数组下标、Map 的 get/set、甚至 for...in 循环,能力远超老门卫。
“记账本”(Dep)和“执行者”(Effect)是怎么配合的
光有门卫不够,还得有本子记谁盯了谁,还得有人收到通知后真去干活。
从零开始编排 SpringBoot+Vue 全栈项目工作流,适用于新建全栈项目或完整脚手架请求,触发后依次调用 product‑spec‑builder(需求调研)等模块。
立即学习“前端免费学习笔记(深入)”;
- Dep(依赖集合) 就是一本本小账本,每个属性一本。比如 count 对应的账本里,存着所有读过它的函数(组件渲染函数、计算属性、watch 回调)
- Effect 就是那个干活的人。Vue 在首次渲染时,会把整个渲染函数包装成一个 Effect。它一运行,里面读到的所有响应式属性,都会被门卫记到账本上
- 等你改数据,门卫翻出 count 的账本,挨个叫上面记着的 Effect:“该干活了!” Effect 就会重新执行,比如重绘组件
为什么嵌套对象不会一开始就全代理?
你写 reactive({ user: { name: '张三' } }),Vue 并不会立刻给 user 也套一层 Proxy。它很聪明:
- 第一次访问 state.user.name 时,门卫发现 user 是个对象,才现场给 user 也请个门卫
- 这样避免了创建大量无用代理,内存和性能都更省
ref 和 reactive 为啥要分开?
因为 Proxy 不能直接代理原始值(数字、字符串、布尔值)。所以 Vue 用 ref 包一层:
- ref(10) 返回的是一个对象 { value: 10 },再对这个对象用 reactive
- 你在模板里写 count.value,触发的是对象属性的 get;你写 count.value = 20,触发的是 set
- 为了方便,Vue 在模板中自动解包 count,让你感觉就像在用普通变量

















