vue 3 响应式核心是 proxy,通过 new proxy(target, handler) 创建代理对象实现全量拦截;依赖收集依赖 targetmap 结构精准关联 effect;proxy 解决 vue2 中 object.defineproperty 的“点监控”缺陷,支持新增/删除属性、数组索引赋值及深层嵌套惰性响应;ref 底层也基于 reactive,包装基本类型为 {value: xxx} 并递归代理。

Vue 3 的响应式核心是 Proxy,它不是给每个属性加锁,而是为整个对象装上一个“智能闸机”——所有读、写、删、查操作都必须经过它,从而实现真正意义上的全量拦截。
Proxy 是怎么接管数据的?
调用 reactive() 时,Vue 并不修改原始对象,而是用 new Proxy(target, handler) 包裹它,生成一个代理对象。这个代理对象对外行为和原对象完全一致,但内部所有操作都会触发 handler 中定义的拦截逻辑:
-
get:读取属性(如
state.count)时触发,用于依赖收集 -
set:赋值修改(如
state.count = 5)时触发,用于派发更新 -
deleteProperty:删除属性(如
delete state.name)也能被捕获 -
has、ownKeys、iterate 等:支持
in操作、Object.keys()、for...in等遍历行为的响应式
依赖收集如何精准关联 effect?
Vue 内部维护一个全局的 targetMap(WeakMap),结构是:target → (depsMap: Map) → key → Set<effect></effect>
- 当执行
effect(() => console.log(state.count))时,该函数被标记为当前活跃 effect - 读取
state.count触发 get 拦截器,自动调用 track(),将当前 effect 记入targetMap.get(state).get('count')对应的 Set 中 - 后续修改
state.count时,set 拦截器调用 trigger(),从同一位置取出所有 effect 并执行
为什么 Proxy 能解决 Vue2 的硬伤?
Object.defineProperty 是“点监控”,只对已存在属性生效;Proxy 是“面监控”,覆盖对象全部行为:
- 新增属性
state.newKey = 'ok':直接触发 set,无需Vue.set - 删除属性
delete state.oldKey:触发 deleteProperty,自动通知更新 - 数组索引赋值
arr[0] = 99:get/set 拦截天然支持,不再依赖重写原型方法 - 深层嵌套访问
state.user.profile.name:get 返回值若为对象,会惰性递归 reactive,避免初始化性能浪费
ref 和 reactive 的底层统一性
ref() 看似不同,实则与 reactive 共享同一套 Proxy 机制:
- ref 把基本类型包装成带
.value属性的对象:{ value: xxx } - 再对这个对象调用 reactive,所以
ref(1)本质是reactive({ value: 1 }) - 模板中使用
{{ count }}时,Vue 编译器自动展开count.value,保持语法简洁
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










