vue怎么实现数据检测
Vue 数据检测的实现方式
Vue 通过响应式系统实现数据检测,核心机制基于 Object.defineProperty(Vue 2)或 Proxy(Vue 3)。以下是具体实现方法:
基于 Vue 2 的 Object.defineProperty
Vue 2 通过递归遍历数据对象,为每个属性添加 getter/setter 拦截操作:
function defineReactive(obj, key, val) {
Object.defineProperty(obj, key, {
get() {
console.log(`读取 ${key}`);
return val;
},
set(newVal) {
if (newVal !== val) {
console.log(`设置 ${key} 为 ${newVal}`);
val = newVal;
}
}
});
}
基于 Vue 3 的 Proxy
Vue 3 使用 ES6 的 Proxy 代理整个对象,无需递归初始化:
function reactive(obj) {
return new Proxy(obj, {
get(target, key) {
console.log(`读取 ${key}`);
return Reflect.get(target, key);
},
set(target, key, value) {
if (target[key] !== value) {
console.log(`设置 ${key} 为 ${value}`);
return Reflect.set(target, key, value);
}
return true;
}
});
}
数组的响应式处理
Vue 对数组方法(push/pop/shift 等)进行重写:
const arrayProto = Array.prototype;
const arrayMethods = Object.create(arrayProto);
['push', 'pop'].forEach(method => {
const original = arrayProto[method];
arrayMethods[method] = function(...args) {
console.log(`数组 ${method} 操作`);
return original.apply(this, args);
};
});
依赖收集与派发更新
Vue 通过 Watcher 和 Dep 类实现依赖管理:
class Dep {
constructor() {
this.subscribers = new Set();
}
depend() {
if (currentWatcher) {
this.subscribers.add(currentWatcher);
}
}
notify() {
this.subscribers.forEach(watcher => watcher.update());
}
}
性能优化注意事项
- 避免动态添加新属性,使用
Vue.set或this.$set - 对大数据量使用
Object.freeze跳过响应式处理 - 合理使用计算属性缓存结果
以上机制共同构成 Vue 的响应式系统,实现数据变化自动检测和视图更新。







