vue如何实现数据响应
Vue 数据响应的实现原理
Vue 的数据响应是通过数据劫持结合发布-订阅模式实现的,核心依赖 Object.defineProperty(Vue 2.x)或 Proxy(Vue 3.x)。以下是具体实现方式:
Vue 2.x 的响应式实现
依赖 Object.defineProperty 进行数据劫持
- 遍历数据对象的属性,通过
Object.defineProperty将属性转换为getter/setter。 - 在
getter中收集依赖(即当前正在执行的 Watcher)。 - 在
setter中触发依赖更新(通知 Watcher 重新计算)。
function defineReactive(obj, key, val) {
const dep = new Dep(); // 依赖管理
Object.defineProperty(obj, key, {
get() {
if (Dep.target) {
dep.depend(); // 收集依赖
}
return val;
},
set(newVal) {
if (newVal === val) return;
val = newVal;
dep.notify(); // 触发更新
}
});
}
依赖收集与派发更新

Dep类负责管理依赖(Watcher),每个响应式属性对应一个Dep实例。Watcher是观察者,在组件渲染或计算属性时创建,负责执行更新逻辑。
Vue 3.x 的响应式实现
基于 Proxy 的响应式
Proxy可以直接代理整个对象,无需递归遍历属性。- 支持动态新增属性的响应式(Vue 2.x 需通过
Vue.set实现)。
function reactive(obj) {
return new Proxy(obj, {
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;
}
});
}
优化点

- 性能更好:
Proxy是浏览器原生支持,无需递归初始化。 - 支持数组和动态属性:无需特殊处理。
响应式系统的核心模块
-
Observer
- 将普通对象转换为响应式对象。
- Vue 2.x 中递归遍历对象属性,Vue 3.x 中直接代理。
-
Dep(依赖管理)
- 每个响应式属性关联一个
Dep实例。 - 存储所有依赖该属性的
Watcher。
- 每个响应式属性关联一个
-
Watcher(观察者)
- 在组件渲染、计算属性或侦听器时创建。
- 触发
getter时被收集到Dep中。
注意事项
- 对象新增属性:Vue 2.x 中需用
Vue.set,Vue 3.x 直接生效。 - 数组响应式:Vue 2.x 通过重写数组方法(如
push、pop)实现。 - 性能优化:避免频繁更新大数据结构,可使用
Object.freeze跳过响应式处理。
通过以上机制,Vue 实现了数据变化时自动更新视图的高效响应式系统。






