vue 监听实现原理
Vue 监听实现原理
Vue 的监听机制主要依赖于响应式系统,通过 Object.defineProperty 或 Proxy 实现数据劫持,并结合观察者模式实现依赖收集和派发更新。
核心机制:响应式系统
Vue 2.x 使用 Object.defineProperty 对对象的属性进行劫持,通过 getter 和 setter 拦截属性的读取和修改操作。当数据被访问时,触发 getter 进行依赖收集;当数据被修改时,触发 setter 通知依赖更新。
Vue 3.x 改用 Proxy 实现响应式,可以监听整个对象而非单个属性,解决了 Vue 2.x 中无法监听新增属性的问题。
依赖收集与派发更新
每个响应式数据会关联一个 Dep(依赖管理器),用于存储所有依赖该数据的 Watcher。当数据被访问时,当前 Watcher 会被添加到 Dep 中;当数据被修改时,Dep 会通知所有 Watcher 执行更新。

Watcher 的作用
Watcher 是观察者,负责执行具体的更新逻辑。分为三种类型:
- 渲染
Watcher:负责组件渲染。 - 计算属性
Watcher:处理计算属性的更新。 - 用户自定义
Watcher:通过watch选项或$watch方法创建。
监听实现示例
以下是一个简化的监听实现代码片段:
// 简化版响应式实现(Vue 2.x 风格)
function defineReactive(obj, key, val) {
const dep = new Dep(); // 依赖管理器
Object.defineProperty(obj, key, {
get() {
if (Dep.target) {
dep.addSub(Dep.target); // 依赖收集
}
return val;
},
set(newVal) {
if (newVal === val) return;
val = newVal;
dep.notify(); // 派发更新
}
});
}
// Dep 类
class Dep {
constructor() {
this.subs = [];
}
addSub(sub) {
this.subs.push(sub);
}
notify() {
this.subs.forEach(sub => sub.update());
}
}
监听 API 的使用
Vue 提供了多种监听数据变化的方式:

-
watch选项:监听特定数据的变化并执行回调。watch: { someData(newVal, oldVal) { // 处理变化 } } -
$watch方法:动态创建监听器。this.$watch('someData', (newVal, oldVal) => { // 处理变化 }); -
计算属性:基于依赖数据的变化自动更新。
computed: { computedData() { return this.someData * 2; } }
性能优化与注意事项
- 避免深度监听复杂对象,可以使用
immediate或deep选项按需开启。 - 在 Vue 3.x 中,
Proxy的性能优于Object.defineProperty,尤其是在处理大型对象时。 - 监听器的回调函数应避免执行耗时操作,以防阻塞渲染。






