Vue 3 中 reactive 对象的属性新增和删除能自动触发响应,核心在于 Proxy 的 get、set 和 deleteProperty 拦截器协同依赖收集与更新调度机制;新增属性由 set 拦截器捕获并 trigger,删除属性由 deleteProperty 拦截器捕获并同时通知 key 和 ITERATE_KEY 依赖。

Vue 3 中 reactive 对象的属性新增和删除能自动触发响应,核心就在于 Proxy 的 get、set 和 deleteProperty 三个拦截器协同工作,配合依赖收集与更新调度机制。它不是靠“监听某个键是否存在”,而是从行为层面统一接管对象操作。
新增属性:set 拦截器自动捕获,无需预定义
Vue 2 必须提前知道所有 key 才能用 Object.defineProperty 绑定 getter/setter;而 Vue 3 的 Proxy 直接代理整个对象,任何赋值操作都会进 set 拦截器:
- 执行
state.newField = 'hello'时,set(target, 'newField', 'hello')被触发 - 内部调用
Reflect.set(target, key, value)完成真实赋值 - 紧接着调用
trigger(target, 'newField'),通知所有依赖该 key 的副作用(如模板渲染、watchEffect)重新执行 - 如果新值是对象,还会在 get 过程中惰性递归调用
reactive(),保证深层响应
删除属性:deleteProperty 拦截器精准捕获
这是 Vue 2 完全做不到的能力——Object.defineProperty 根本无法监听 delete 行为。Vue 3 则原生支持:
根据项目规范生成 React 和 Vue 组件,包括 TypeScript 类型定义、Ant Design 5 集成、Tailwind CSS 样式及 Vitest 测试文件。当用户提出创建、生成或搭建前端组件的需求时启用,例如:“帮我写一个表格组件”、“生成一个弹窗”、“create a form component”、“写一个列表页”、“生成一个下拉选择器”。该能力在以下任一场景触发:涉及 React/TSX/Vue 组件生成、UI 组件创建,或为组件生成测试文件。
- 执行
delete state.age时,deleteProperty(target, 'age')被触发 - 先用
Reflect.deleteProperty(target, key)执行真实删除 - 再调用
trigger(target, 'age'),但注意:这里会额外触发一个特殊依赖ITERATE_KEY(用于 for...in、Object.keys 等遍历场景),因为删字段会影响枚举结果 - 所有监听
state.age的地方(比如{{ state.age }})和监听整个对象结构的地方(比如v-for="item in state")都会收到通知
为什么新增/删除都能“立刻响应”?关键在依赖的粒度设计
Vue 3 不是给每个属性建一个 Dep 实例,而是按“操作类型 + 键名”做细粒度依赖管理:
立即学习“前端免费学习笔记(深入)”;
-
track(target, 'get', key):读取state.name时,把当前 effect 记入name对应的依赖集 -
track(target, 'iterate', ITERATE_KEY):执行for (let k in state)时,把 effect 记入一个全局迭代依赖集 -
trigger(target, 'set', key)或trigger(target, 'delete', key):不仅通知key的直接依赖,还同步通知ITERATE_KEY依赖,确保遍历逻辑也更新
实际开发中要注意的边界
Proxy 能力强大,但不是万能的:
- 只对 reactive 创建的代理对象生效,普通对象或解构后的值(
const { count } = state)不再受控 - 新增/删除对
ref包裹的基本类型无效(ref 靠 .value 触发 set/get) - 数组索引赋值(
arr[10] = x)、length 修改、甚至arr.push()都天然响应,因为这些操作最终都落在 set 或 deleteProperty 上 - 嵌套对象新增属性,只要外层是 reactive,内层也会在首次访问时被自动 reactive 化(惰性代理)

















