vue响应式实现
Vue 响应式实现原理
Vue 的响应式系统是其核心特性之一,通过数据劫持和依赖收集实现。以下是 Vue 2.x 和 Vue 3.x 响应式实现的主要机制:

Vue 2.x 的响应式实现
Vue 2.x 使用 Object.defineProperty 实现数据劫持,通过 getter 和 setter 拦截属性的访问和修改。

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(); // 通知更新
}
});
}
- 依赖收集:在 getter 中通过
Dep.target(当前 Watcher)收集依赖。 - 派发更新:在 setter 中通过
dep.notify()通知所有 Watcher 更新。
Vue 3.x 的响应式实现
Vue 3.x 使用 Proxy 替代 Object.defineProperty,解决了 Vue 2.x 无法监听新增属性和数组变化的问题。
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) {
const result = Reflect.set(target, key, value, receiver);
trigger(target, key); // 触发更新
return result;
}
});
}
track和trigger:分别用于依赖收集和派发更新。- Reflect API:配合
Proxy实现更规范的拦截行为。
依赖收集与派发更新
- Dep 类:管理依赖(Watcher),通过
depend收集和notify派发。 - Watcher 类:观察数据变化并执行回调(如更新视图)。
class Dep {
constructor() {
this.subscribers = new Set();
}
depend() {
if (Dep.target) this.subscribers.add(Dep.target);
}
notify() {
this.subscribers.forEach(watcher => watcher.update());
}
}
数组的响应式处理
Vue 2.x 通过重写数组方法(如 push、pop)实现响应式:
const arrayProto = Array.prototype;
const arrayMethods = Object.create(arrayProto);
['push', 'pop', 'shift'].forEach(method => {
const original = arrayProto[method];
arrayMethods[method] = function(...args) {
const result = original.apply(this, args);
this.__ob__.dep.notify(); // 手动触发更新
return result;
};
});
总结对比
- Vue 2.x:基于
Object.defineProperty,需递归遍历对象,无法监听新增属性。 - Vue 3.x:基于
Proxy,支持动态属性监听,性能更优。
响应式系统的核心是通过数据劫持自动追踪依赖,在数据变化时高效更新相关视图或逻辑。






