当前位置:首页 > VUE

vue watch实现原理

2026-01-17 00:13:38VUE

vue watch实现原理

Vue 的 watch 实现原理

Vue 的 watch 功能基于响应式系统的依赖收集和派发更新机制实现。核心原理是通过监听数据变化并触发回调函数。

依赖收集阶段

  • 在组件初始化时,Vue 会遍历 watch 选项,为每个被监听属性创建对应的 Watcher 实例。
  • 这些 Watcher 会将被监听属性添加到自己的依赖列表中。
  • 当属性被访问时,触发 getterWatcher 会被当前属性的 Dep(依赖管理器)收集。

派发更新阶段

  • 当被监听属性发生变化时,触发 setter
  • setter 会通知对应的 DepDep 会遍历所有订阅它的 Watcher 并调用 update 方法。
  • Watcherupdate 方法会执行注册的回调函数,并将新旧值作为参数传入。

深度监听实现

  • 如果设置了 deep: true,Vue 会递归遍历被监听对象的所有属性。
  • 为每个子属性也创建 Watcher,确保嵌套属性变化也能触发回调。

立即触发实现

  • 如果设置了 immediate: true,Vue 会在 Watcher 创建后立即执行一次回调函数。
  • 此时旧值为 undefined,新值为当前属性值。

异步更新机制

  • 默认情况下,watch 的回调是异步执行的。
  • Vue 会将回调推入异步队列,等待当前事件循环结束后统一执行。
  • 可以通过 sync: true 选项强制同步执行。

源码关键逻辑

// 简化版实现逻辑
function createWatcher(vm, expOrFn, handler, options) {
  const watcher = new Watcher(vm, expOrFn, handler, {
    deep: !!options.deep,
    immediate: !!options.immediate,
    sync: !!options.sync
  });

  if (options.immediate) {
    handler.call(vm, watcher.value);
  }

  return function unwatchFn() {
    watcher.teardown();
  }
}

与计算属性的区别

  • watch 允许执行异步操作,计算属性必须是同步的。
  • watch 更通用,可以监听任何数据变化,计算属性基于其依赖进行缓存。
  • watch 没有返回值,计算属性必须返回一个值。

性能优化建议

  • 避免过度使用深度监听,特别是大型对象。
  • 对于需要监听多个属性的情况,考虑使用计算属性 + watch 的组合。
  • 在不需要时及时调用 unwatch 函数取消监听。

vue watch实现原理

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

相关文章

vue实现tab切换

vue实现tab切换

Vue实现Tab切换的方法 使用v-if和v-show指令 通过v-if或v-show控制不同tab内容的显示与隐藏。v-if会销毁和重建DOM,适合切换频率低的场景;v-show仅切换CSS的dis…

vue 实现长列表

vue 实现长列表

Vue 实现长列表的优化方案 虚拟滚动技术 虚拟滚动是处理长列表的高效方式,仅渲染可视区域内的元素。通过计算滚动位置动态加载和卸载DOM节点,大幅减少内存占用和渲染压力。 <template&…

vue实现tab换行

vue实现tab换行

Vue实现Tab切换的常见方法 使用Vue实现Tab切换功能可以通过多种方式完成,以下是几种常见的方法: 动态组件结合v-if或v-show 通过v-if或v-show控制不同Tab内容的显示…

vue实现选择本地文件

vue实现选择本地文件

实现文件选择功能 在Vue中实现本地文件选择可以通过HTML原生的<input type="file">元素实现。创建一个基本的文件选择组件: <template> &l…

vue实现按钮组轮换

vue实现按钮组轮换

实现按钮组轮换的方法 在Vue中实现按钮组轮换效果可以通过动态绑定类和事件处理来完成。以下是一种常见的实现方式: 模板部分 <template> <div class="bu…

vue实现签约合作弹窗

vue实现签约合作弹窗

实现签约合作弹窗的步骤 使用Vue实现签约合作弹窗可以通过组件化方式完成,结合模态框和表单交互逻辑。以下是具体实现方法: 1. 创建弹窗组件 新建一个Vue组件文件(如SignContractDia…