vue怎样实现响应式
Vue 响应式实现原理
Vue 的响应式系统基于 Object.defineProperty(Vue 2)或 Proxy(Vue 3)实现,核心是通过数据劫持结合发布-订阅模式自动追踪依赖并触发更新。
Vue 2 实现方式
-
数据劫持
- 通过
Object.defineProperty递归遍历对象的属性,将其转换为 getter/setter。 - 示例代码:
function defineReactive(obj, key, val) { Object.defineProperty(obj, key, { get() { console.log(`读取 ${key}`); return val; }, set(newVal) { if (newVal === val) return; console.log(`更新 ${key}`); val = newVal; } }); }
- 通过
-
依赖收集
- 在 getter 中收集依赖(如 Watcher 实例),在 setter 中通知依赖更新。
- 每个响应式属性关联一个
Dep实例管理依赖。
-
数组处理

- 重写数组的
push、pop等变异方法,在调用时手动触发更新。
- 重写数组的
Vue 3 实现方式
-
Proxy 代理
- 使用
Proxy直接代理整个对象,无需递归初始化属性。 - 示例代码:
const reactive = (target) => { return new Proxy(target, { get(target, key, receiver) { track(target, key); // 依赖收集 return Reflect.get(target, key, receiver); }, set(target, key, value, receiver) { Reflect.set(target, key, value, receiver); trigger(target, key); // 触发更新 return true; } }); };
- 使用
-
Reflect 反射

- 配合
Reflect操作对象,避免直接操作原对象。
- 配合
-
性能优化
- 惰性响应式:仅在访问属性时创建响应式。
- 嵌套属性自动代理,无需手动递归。
手动实现响应式的方法
-
使用
reactive/ref(Vue 3)import { reactive, ref } from 'vue'; const state = reactive({ count: 0 }); // 对象 const num = ref(1); // 基本类型 -
自定义响应式逻辑
- 基于
Proxy实现简易响应式:function createReactiveObject(target) { const handlers = { get(target, key) { console.log(`获取 ${key}`); return target[key]; }, set(target, key, value) { console.log(`设置 ${key}`); target[key] = value; return true; } }; return new Proxy(target, handlers); }
- 基于
注意事项
- 避免直接解构响应式对象:解构会失去响应性,需使用
toRefs。 - 动态添加属性:Vue 2 需用
Vue.set,Vue 3 可直接添加。 - 性能影响:深度响应式转换可能对大型对象产生开销。






