当前位置:首页 > VUE

vue watch 实现原理

2026-02-18 17:34:33VUE

Vue Watch 实现原理

Vue 的 watch 功能用于监听数据变化并执行回调函数。其核心实现基于 Vue 的响应式系统,依赖 Object.definePropertyProxy(Vue 3)进行数据劫持,并通过依赖收集和派发更新机制实现监听。

依赖收集与派发更新

当初始化 watch 时,Vue 会将监听的回调函数作为依赖收集到当前数据的依赖列表中。数据变化时,触发 setterProxy 的拦截逻辑,通知所有依赖(Watcher 实例)执行回调。

Watcher 类

Vue 内部通过 Watcher 类实现监听逻辑。Watcher 分为三类:渲染 Watcher、计算属性 Watcher 和用户自定义 Watcher(即 watch 选项)。watch 的每个监听项会创建一个 Watcher 实例。

// 伪代码示例
class Watcher {
  constructor(vm, expOrFn, cb, options) {
    this.vm = vm;
    this.cb = cb;
    this.getter = parsePath(expOrFn); // 解析监听路径(如 'a.b.c')
    this.value = this.get(); // 触发依赖收集
  }

  get() {
    pushTarget(this); // 将当前 Watcher 设置为全局正在计算的 Watcher
    const value = this.getter.call(this.vm, this.vm); // 触发数据属性的 getter
    popTarget(); // 恢复之前的 Watcher
    return value;
  }

  update() {
    const oldValue = this.value;
    this.value = this.get(); // 重新获取值
    this.cb.call(this.vm, this.value, oldValue); // 执行回调
  }
}

监听触发流程

  1. 初始化阶段:解析 watch 选项,为每个监听属性创建 Watcher 实例,并设置回调函数。
  2. 依赖收集:首次调用 Watcher.get() 时,触发监听属性的 getter,将当前 Watcher 添加到依赖列表中。
  3. 数据更新:监听属性被修改时,触发 setterProxy 拦截,调用依赖列表中所有 Watcher 的 update 方法。
  4. 回调执行Watcher.update() 对比新旧值,若变化则执行用户定义的回调函数。

深度监听实现

当设置 deep: true 时,Vue 会递归遍历监听对象的所有子属性,为每个子属性触发 getter,从而收集依赖。

// 伪代码:深度监听
function traverse(val) {
  if (typeof val !== 'object') return;
  for (const key in val) {
    traverse(val[key]); // 递归触发子属性的 getter
  }
}

立即触发与旧值获取

  • immediate: true:初始化时直接调用一次回调函数。
  • 旧值通过 Watcher 实例的 this.value 缓存,在 update 时作为参数传递给回调。

Vue 3 的优化

Vue 3 使用 Proxy 替代 Object.defineProperty,解决了数组和新增属性的监听问题。watch 的实现改为基于 effectReactiveEffect 类,原理类似但更高效。

vue watch 实现原理

标签: 原理vue
分享给朋友:

相关文章

vue实现选择分类

vue实现选择分类

Vue 实现选择分类的方法 使用 v-model 绑定选择值 在 Vue 中可以通过 v-model 指令实现双向数据绑定,适用于下拉选择框(<select>)。以下是一个基本示例: &…

vue设计与实现目录

vue设计与实现目录

以下是《Vue设计与实现》一书的典型目录结构(根据常见技术书籍及Vue核心内容整理): 响应式系统 响应式数据的基本原理 依赖收集与触发更新 实现简易响应式系统 Proxy与Refle…

vue优秀实现

vue优秀实现

Vue.js 优秀实现方法 响应式数据管理 使用 Vue 的 ref 和 reactive 处理基础类型和对象类型数据,结合 computed 计算属性优化渲染性能。对于复杂状态,推荐 Pinia 替…

vue实现贴图

vue实现贴图

Vue 实现贴图功能 在Vue中实现贴图功能通常涉及将图片动态添加到指定位置或元素上。以下是几种常见实现方式: 使用v-bind动态绑定图片 通过数据驱动的方式动态更换图片源: <templ…

vue 实现tabs

vue 实现tabs

Vue 实现 Tabs 组件的方法 使用动态组件和 v-for 在 Vue 中实现 Tabs 可以通过动态组件和 v-for 指令结合完成。定义一个 tabs 数组,包含每个标签的标题和对应的组件。…

vue实现alert

vue实现alert

实现自定义 Alert 组件 在 Vue 中可以通过组件化方式实现自定义 Alert 弹窗。以下是基于 Vue 3 的实现示例: 组件代码 (Alert.vue) <template>…