当前位置:首页 > 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,从而收集依赖。

vue watch 实现原理

// 伪代码:深度监听
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
分享给朋友:

相关文章

vue实现frame

vue实现frame

Vue 中实现 iframe 的方法 在 Vue 中可以通过直接使用 <iframe> 标签或动态绑定 src 属性来实现 iframe 功能。 基本用法 <template&g…

vue实现slidetoggle

vue实现slidetoggle

Vue 实现 SlideToggle 效果 SlideToggle 是一种常见的交互效果,元素以滑动方式展开或收起。以下是几种实现方法: 使用 CSS Transition 和 v-show…

vue实现验证

vue实现验证

Vue 表单验证实现方法 在Vue中实现表单验证可以通过多种方式完成,以下是常见的几种方法: 使用Vuelidate库 Vuelidate是一个轻量级的Vue表单验证库,安装后可以通过简单的配置实现…

vue 实现图钉

vue 实现图钉

实现图钉效果的步骤 在Vue中实现图钉(固定位置)效果,可以通过CSS的position: sticky属性或监听滚动事件动态修改元素样式。以下是两种常见方法: 方法一:使用CSS的posi…

vue实现标注

vue实现标注

Vue 实现标注功能的方法 使用 Vue 实现标注功能可以通过多种方式实现,以下介绍几种常见的方法: 1. 使用 HTML5 Canvas 实现标注 Canvas 提供了强大的绘图能力,适合实现复…

vue实现eventbus

vue实现eventbus

Vue 中实现 EventBus 在 Vue 中,EventBus 是一种跨组件通信的机制,尤其适用于非父子组件之间的数据传递。以下是实现 EventBus 的几种方法: 方法一:使用 Vue 实例…