vue如何实现数据监听
Vue 数据监听的实现方式
Vue 主要通过数据劫持和发布-订阅模式实现数据监听,核心是 Object.defineProperty(Vue 2)或 Proxy(Vue 3)。以下是具体实现方法:
使用 Object.defineProperty(Vue 2)
通过劫持对象的属性访问和修改,触发依赖收集和更新通知。

// 简易实现
function defineReactive(obj, key, val) {
const dep = new Dep(); // 依赖收集器
Object.defineProperty(obj, key, {
get() {
dep.depend(); // 收集依赖
return val;
},
set(newVal) {
if (newVal === val) return;
val = newVal;
dep.notify(); // 通知更新
}
});
}
- 依赖收集:在
getter中通过Dep类收集当前属性的依赖(如 Watcher)。 - 触发更新:在
setter中通过Dep.notify()通知所有依赖执行更新。
使用 Proxy(Vue 3)
Proxy 可以监听整个对象,无需递归遍历属性,性能更好。

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;
}
});
}
- 优势:支持监听动态新增属性、数组索引修改等场景。
监听数组变化
Vue 2 通过重写数组方法(如 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);
dep.notify(); // 触发更新
return result;
};
});
手动监听:$watch API
Vue 提供 $watch 方法手动监听数据变化:
export default {
data() {
return { count: 0 };
},
created() {
this.$watch('count', (newVal, oldVal) => {
console.log(`count变化:${oldVal} -> ${newVal}`);
});
}
};
- 深度监听:通过
{ deep: true }监听嵌套对象。
注意事项
- 性能开销:频繁监听大型对象可能影响性能,建议拆分数据。
- 异步更新:Vue 的更新是异步的,多次修改会合并为一次渲染。
- 避免循环引用:监听循环引用对象可能导致栈溢出。






