vue为啥能实现监听
Vue 实现监听的原理
Vue 的监听能力主要基于其响应式系统,该系统通过数据劫持和依赖收集实现。当数据变化时,系统能自动触发视图更新或执行回调函数。
核心机制:Object.defineProperty 或 Proxy
Vue 2.x 使用 Object.defineProperty 对对象的属性进行劫持,通过定义 getter 和 setter 实现数据监听。当属性被访问时,getter 会收集依赖(如模板中的渲染函数或计算属性);当属性被修改时,setter 会通知依赖进行更新。
Vue 3.x 改用 Proxy 代理整个对象,能直接监听对象和数组的变化,无需递归遍历属性或重写数组方法。Proxy 提供了更全面的拦截能力,支持动态新增属性的监听。

依赖收集与派发更新
依赖收集:在 getter 中,当前执行的 Watcher(如组件渲染函数)会被记录为属性的依赖。Vue 通过一个全局的 Dep 类管理依赖关系。
派发更新:在 setter 或 Proxy 的拦截器中,当数据变化时,会触发 Dep.notify() 通知所有 Watcher 执行更新。Watcher 可能重新渲染组件、执行计算属性或用户定义的 watch 回调。

示例代码:Vue 2.x 的响应式实现片段
function defineReactive(obj, key, val) {
const dep = new Dep(); // 管理依赖的实例
Object.defineProperty(obj, key, {
get() {
if (Dep.target) { // 当前运行的 Watcher
dep.addSub(Dep.target); // 收集依赖
}
return val;
},
set(newVal) {
if (newVal === val) return;
val = newVal;
dep.notify(); // 通知更新
}
});
}
数组的特殊处理
Vue 2.x 中,由于 Object.defineProperty 无法监听数组索引变化,Vue 重写了数组的 push、pop 等原型方法。这些方法被调用时会手动触发更新通知。
Vue 3.x 的 Proxy 可以直接监听数组索引和长度变化,无需特殊处理。
异步更新队列
为提高性能,Vue 将数据变更后的更新操作放入异步队列。多次数据修改会合并为一次视图更新,通过 nextTick 机制确保更新完成后执行用户回调。






