当前位置:首页 > 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 实现类似的依赖追踪,逻辑更简洁且性能更好。

vue组件watch实现原理

注意事项

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

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

相关文章

vue实现组件

vue实现组件

Vue 实现组件的方法 Vue 中实现组件可以通过多种方式,包括全局注册、局部注册、单文件组件(SFC)等。以下是常见的实现方法。 全局注册组件 全局注册的组件可以在任何 Vue 实例或组件中使用。…

vue动画实现原理

vue动画实现原理

Vue动画实现原理 Vue的动画系统基于CSS过渡和动画,结合Vue的响应式系统,提供声明式的方式管理元素进入/离开的动画效果。核心原理分为以下几个部分: 过渡类名自动应用 Vue在元素插入/删除时…

vue表格组件实现

vue表格组件实现

Vue表格组件实现 基础表格实现 使用el-table组件实现基础表格功能。安装Element UI后,引入el-table和el-table-column组件。 <template>…

如何缓存react组件

如何缓存react组件

缓存React组件的方法 React.memo 使用React.memo对函数组件进行浅比较缓存,避免不必要的重新渲染。适用于props不变的场景。 const MemoizedComponen…

vue vif实现原理

vue vif实现原理

Vue v-if 实现原理 Vue 的 v-if 指令通过条件渲染控制 DOM 元素的显示与隐藏。其实现原理基于虚拟 DOM 和编译阶段的代码生成。 编译阶段 模板中的 v-if 会被编译为渲染函数…

vue实现组件刷新

vue实现组件刷新

强制重新渲染组件 使用 this.$forceUpdate() 方法可以强制 Vue 实例重新渲染,但不会更新子组件。适用于依赖非响应式数据的情况。 methods: { refreshComp…