当前位置:首页 > VUE

vue组件watch实现原理

2026-01-22 21:32:27VUE

Vue 组件 watch 实现原理

Vue 的 watch 功能用于监听数据变化并执行回调函数。其核心原理基于 Vue 的响应式系统和依赖收集机制。

响应式系统基础

Vue 通过 Object.defineProperty(Vue 2)或 Proxy(Vue 3)实现数据劫持。当数据被访问时,依赖会被收集;当数据被修改时,依赖会被通知并触发更新。

watch 的工作流程

  1. 初始化监听
    在组件初始化阶段,Vue 会遍历 watch 选项中定义的属性,为每个属性创建一个 Watcher 实例。这个 Watcher 会记录回调函数和监听的目标路径。

  2. 依赖收集
    当首次执行 watch 时,会读取被监听属性的值,触发其 getter。此时,Watcher 会被添加到该属性的依赖列表中(即 Dep 实例的订阅者列表)。

  3. 触发回调
    当被监听的属性值发生变化时,会触发 setter,通知所有订阅该属性的 Watcher 执行更新。Watcher 会执行回调函数,并传入新值和旧值。

源码关键逻辑(Vue 2 示例)

// 简化版 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); // 执行回调
  }
}

深层监听与立即执行

  • deep: true
    递归遍历监听对象的所有子属性,为每个子属性绑定同样的依赖收集逻辑。
  • immediate: true
    在初始化时立即执行一次回调,此时旧值为 undefined

Vue 3 的优化

Vue 3 改用 Proxy 实现响应式,watch 通过 effectReactiveEffect 实现类似的依赖追踪,逻辑更简洁且性能更好。

注意事项

  • 避免在回调中修改监听的数据,可能导致无限循环。
  • 对于复杂对象,使用 deep 监听可能带来性能开销,建议明确指定需要监听的子属性。

vue组件watch实现原理

标签: 组件原理
分享给朋友:

相关文章

vue如何实现原理

vue如何实现原理

Vue 的核心实现原理 Vue 的核心原理主要包括响应式系统、虚拟 DOM、模板编译和组件化。以下分模块详细说明其实现机制。 响应式系统 Vue 2.x 使用 Object.definePrope…

vue实现组件拖放

vue实现组件拖放

Vue 实现组件拖放的方法 使用 HTML5 原生拖放 API HTML5 提供了原生的拖放 API,可以通过 draggable 属性、dragstart、dragend、dragover 和 dr…

eventbus实现原理vue

eventbus实现原理vue

EventBus 的实现原理(Vue) EventBus 是 Vue 中实现跨组件通信的一种简单机制,其核心原理基于发布-订阅模式(Pub-Sub)。以下是其实现的关键点: 核心机制 事件中心 E…

vue哪个组件实现动画

vue哪个组件实现动画

在Vue中实现动画效果,可以通过以下组件和方法实现: Vue内置动画组件 Vue提供了<transition>和<transition-group>两个内置组件,用于处理进…

vue动态渲染实现原理

vue动态渲染实现原理

Vue 动态渲染实现原理 Vue 的动态渲染主要依赖于其响应式系统和虚拟 DOM 技术。以下是核心实现原理的详细分析: 响应式系统 Vue 通过 Object.defineProperty(Vue…

vue组件传值实现分页

vue组件传值实现分页

Vue组件传值实现分页的方法 在Vue中实现分页功能,通常需要父子组件之间的数据传递。以下是几种常见的传值方式: 使用props传递数据 父组件通过props向子组件传递当前页码和总页数等分页信息…