vue实现响应式
Vue 响应式原理
Vue 的响应式系统是其核心特性之一,允许数据变化时自动更新视图。以下是 Vue 实现响应式的关键机制:

数据劫持与依赖收集
Vue 2 使用 Object.defineProperty 对数据对象的属性进行劫持。当访问属性时,会触发 getter 收集依赖(Watcher);当修改属性时,会触发 setter 通知依赖更新。

// 简化版数据劫持示例
function defineReactive(obj, key, val) {
const dep = new Dep(); // 依赖管理
Object.defineProperty(obj, key, {
get() {
dep.depend(); // 收集当前 Watcher
return val;
},
set(newVal) {
if (newVal === val) return;
val = newVal;
dep.notify(); // 通知更新
}
});
}
依赖管理(Dep 和 Watcher)
- Dep:每个响应式属性对应一个 Dep 实例,用于存储所有依赖该属性的 Watcher。
- Watcher:代表一个依赖项,可能是组件渲染函数、计算属性或用户自定义的侦听器。
数组响应式处理
Vue 2 通过重写数组的 push、pop、splice 等方法来触发更新。这些方法被包裹以实现响应式通知。
// 数组方法重写示例
const arrayProto = Array.prototype;
const arrayMethods = Object.create(arrayProto);
['push', 'pop', 'splice'].forEach(method => {
const original = arrayProto[method];
arrayMethods[method] = function(...args) {
const result = original.apply(this, args);
dep.notify(); // 触发更新
return result;
};
});
Vue 3 的 Proxy 优化
Vue 3 改用 Proxy 实现响应式,解决了 Vue 2 中无法检测新增属性和数组索引变化的问题。
// Vue 3 响应式示例
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;
}
});
};
响应式 API 对比
| 特性 | Vue 2 (Object.defineProperty) |
Vue 3 (Proxy) |
|---|---|---|
| 检测新增属性 | 需使用 Vue.set |
直接支持 |
| 数组索引变化 | 部分方法需重写 | 直接支持 |
| 性能 | 稍慢(递归劫持) | 更快 |
实践注意事项
- 避免直接修改数组索引或对象未声明的属性(Vue 2)。
- 复杂数据结构可通过
Vue.set或this.$set确保响应式(Vue 2)。 - Vue 3 的
ref和reactive已内置深度响应式处理。






