vue3用proxy实现响应式,重构数据追踪逻辑:代理整个对象、按需建立依赖、支持原生集合类型、统一副作用触发机制,显著提升性能与灵活性。

Vue3用Proxy实现响应式,不是简单替换API,而是重构了整个数据追踪逻辑——它不再逐个定义属性,而是代理整个对象,只在真正访问时才建立依赖关系,从而避免了Vue2中初始化时的全量递归劫持。
Proxy 拦截整个对象,不依赖属性预定义
Vue2必须在初始化时遍历对象所有属性,用Object.defineProperty把每个key都变成getter/setter。哪怕某个属性后续从不被读取,也已被劫持,白白消耗内存和性能。Vue3的Proxy直接包裹目标对象,get/set/delete等操作一并拦截,新增属性、删除属性、修改length,全部天然响应,无需Vue.set或Vue.delete。
- 添加新字段:
state.newProp = 'hello'→ 视图立刻更新 - 删除字段:
delete state.oldProp→ 依赖自动清理 - 数组索引赋值:
list[2] = 'updated'→ 不再需要特殊方法
按需收集依赖,减少无效监听
Vue2在init阶段就为所有属性建立依赖映射,不管它们是否被模板或计算属性用到。Vue3则在属性首次被读取(get)时才调用track收集当前effect,没访问过的属性根本不注册依赖。大数据列表渲染时,仅渲染可见区域的项触发响应式,其余保持“惰性”,显著降低初始化开销。
- 访问
obj.name才收集name的依赖,obj.age未读则无开销 - 嵌套对象也延迟代理:只有访问
obj.nested.x时,才对nested做reactive处理
统一支持多种数据结构
Object.defineProperty只能作用于普通对象属性,对Map、Set、WeakMap等原生集合类型束手无策。Proxy可代理任意对象,包括Map、Set、Array甚至函数,Vue3因此能原生支持ref(new Map())或reactive(new Set()),且增删元素全程响应。
-
map.set('key', value)→ 自动触发依赖更新 -
set.add(item)→ 无需包装,直接响应 - 不再需要为不同结构写不同适配逻辑
更干净的副作用触发机制
Vue3的set拦截器中,先执行Reflect.set()完成赋值,再调用trigger通知依赖更新;而Vue2的setter里混杂了赋值、依赖通知、队列调度等逻辑。这种分离让响应式系统更可预测,也便于开发者用watchEffect精准控制副作用时机。
- 修改属性后,trigger只通知真正订阅该key的effect,不误伤无关逻辑
- 结合
shallowRef或markRaw,可主动排除某些对象的响应式代理
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










