vue数据响应式实现
Vue 数据响应式实现原理
Vue 的数据响应式核心是通过 Object.defineProperty(Vue 2)或 Proxy(Vue 3)实现的。以下是具体实现方式:

Vue 2 的实现
Vue 2 使用 Object.defineProperty 对对象的属性进行劫持,通过 getter 和 setter 监听数据变化。

function defineReactive(obj, key, val) {
Object.defineProperty(obj, key, {
enumerable: true,
configurable: true,
get() {
console.log(`获取 ${key}: ${val}`);
return val;
},
set(newVal) {
if (newVal === val) return;
console.log(`设置 ${key}: ${newVal}`);
val = newVal;
// 触发视图更新
}
});
}
const data = { name: 'Vue' };
defineReactive(data, 'name', data.name);
data.name = 'Vue 2'; // 触发 setter
- 局限性:
- 无法监听新增或删除的属性(需使用
Vue.set或Vue.delete)。 - 对数组的变异方法(如
push、pop)需通过重写实现响应式。
- 无法监听新增或删除的属性(需使用
Vue 3 的实现
Vue 3 改用 Proxy 实现响应式,解决了 Vue 2 的局限性。
function reactive(obj) {
return new Proxy(obj, {
get(target, key) {
console.log(`获取 ${key}: ${target[key]}`);
return target[key];
},
set(target, key, value) {
if (target[key] === value) return true;
console.log(`设置 ${key}: ${value}`);
target[key] = value;
// 触发视图更新
return true;
}
});
}
const data = reactive({ name: 'Vue' });
data.name = 'Vue 3'; // 触发 setter
- 优势:
- 直接监听对象而非属性,支持新增和删除属性。
- 默认支持数组索引和长度的变化。
依赖收集与派发更新
Vue 通过 依赖收集(Dependency Tracking)和 派发更新(Dependency Triggering)实现视图的自动更新。
- 依赖收集:在 getter 中收集当前依赖(如组件的渲染函数)。
- 派发更新:在 setter 中通知依赖进行更新。
// 简化版的依赖管理
let activeEffect;
class Dep {
constructor() {
this.subscribers = new Set();
}
depend() {
if (activeEffect) this.subscribers.add(activeEffect);
}
notify() {
this.subscribers.forEach(effect => effect());
}
}
function watchEffect(effect) {
activeEffect = effect;
effect();
activeEffect = null;
}
const dep = new Dep();
const data = reactive({
count: 0
});
watchEffect(() => {
console.log(`Count: ${data.count}`); // 触发 getter,收集依赖
});
data.count++; // 触发 setter,通知更新
总结
- Vue 2:基于
Object.defineProperty,需额外处理数组和新增属性。 - Vue 3:基于
Proxy,原生支持对象和数组的全面监听。 - 核心机制:依赖收集(getter)和派发更新(setter)实现数据与视图的同步。






