Vue3响应式核心是Proxy代理+依赖收集与触发更新机制:通过Proxy拦截对象操作实现全属性监听,get时用activeEffect收集依赖,set时精准通知对应effect函数重新执行。

响应式核心:用 Proxy 代理数据
Vue3 不再像 Vue2 那样用 Object.defineProperty 去劫持每个属性,而是用 Proxy 包裹整个对象。这样能监听到新增/删除属性、数组索引赋值、length 修改等 Vue2 无法捕获的操作。
当你写 const state = reactive({ count: 0 }),Vue 内部其实是:
- 创建一个 Proxy,拦截 get/set/deleteProperty 等操作
- get 时记录谁在读这个值(即“依赖收集”)
- set 时通知所有读过它的函数重新执行(即“触发更新”)
依赖收集:谁在读,就记谁
依赖不是自动收集的,必须运行在“响应式副作用函数”里才会被跟踪——比如 setup() 中的 computed、watch,或模板编译后生成的渲染函数。
关键机制叫 activeEffect:它是一个全局变量,临时存着当前正在执行的响应式函数。
立即学习“前端免费学习笔记(深入)”;
从零开始编排 SpringBoot+Vue 全栈项目工作流,适用于新建全栈项目或完整脚手架请求,触发后依次调用 product‑spec‑builder(需求调研)等模块。
- 进入 setup 或 computed 时,Vue 把该函数设为 activeEffect
- 访问
state.count触发 Proxy 的 get 拦截器 - get 里会把 activeEffect 添加到
count对应的依赖集合(Dep)中 - 这个过程就像“登记表”:谁看了 count,就往 count 的小本本上记一笔
依赖存储:每个响应式字段都有自己的“通知名单”
Vue3 内部为每个响应式属性维护一个 WeakMap + Map + Set 结构:
- targetMap(WeakMap):以原始对象为 key,值是另一个 Map
- depsMap(Map):以属性名(key)为 key,值是依赖集合(Set)
- dep(Set):存放所有依赖这个属性的 effect 函数
简单说:对象 → 属性 → 一堆要通知的函数。这样修改某个字段,只通知真正关心它的人,不浪费性能。
触发更新:改值时,挨个唤醒它们
当 state.count++,Proxy 的 set 拦截器被触发:
- 从 targetMap 找到该对象的 depsMap
- 从 depsMap 找到
'count'对应的 dep(Set) - 遍历 dep,逐个执行里面的 effect 函数(比如重新渲染组件、更新 computed)
- 如果 effect 是 watch,还会做新旧值比对等额外逻辑
注意:effect 默认是“懒执行”的,只有首次运行时才收集依赖;后续只在依赖变化时才重跑。
图解一句话总结
你写的响应式代码,像走进一间带登记簿的图书馆:
→ 看书(读属性)前先签到(get 时把当前函数记进 dep);
→ 图书管理员(set)一看到某本书被修改,立刻翻出登记簿,打电话通知所有签过到的人来重读。

















