当前位置:首页 > VUE

vue watch 实现 原理

2026-01-15 05:06:48VUE

Vue Watch 实现原理

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

响应式系统基础

Vue 的响应式系统通过以下步骤实现:

  1. 数据劫持:使用 Object.defineProperty(Vue 2)或 Proxy(Vue 3)拦截数据的读取和修改操作。
  2. 依赖收集:在数据被访问时,收集当前正在计算的依赖(如 watch 回调)。
  3. 派发更新:在数据被修改时,通知所有依赖执行更新。

Watch 的工作流程

  1. 初始化阶段
    当在 Vue 实例中定义 watch 时,Vue 会遍历 watch 的配置项,为每个被监听的数据创建一个 Watcher 实例。

    new Vue({
      data: { count: 0 },
      watch: {
        count(newVal, oldVal) {
          console.log('count changed:', oldVal, '->', newVal);
        }
      }
    });
  2. 依赖收集
    Watcher 实例会在初始化时调用 get 方法,触发被监听数据的 getter,从而将当前 Watcher 添加到依赖列表中(Dep 的 subs 数组)。

  3. 数据变化触发回调
    当被监听的数据被修改时,会触发 setterProxy 的拦截逻辑,通知依赖列表中的所有 Watcher 执行 update 方法。
    Watcherupdate 方法会调用回调函数,并传入新值和旧值。

    vue watch 实现 原理

源码核心逻辑(Vue 2)

  1. Watcher 类
    Watcherwatch 的核心实现,负责管理依赖和回调执行。

    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 设置为全局正在计算的依赖
        const value = this.getter.call(this.vm, this.vm); // 触发 getter
        popTarget(); // 恢复之前的依赖
        return value;
      }
    
      update() {
        const oldValue = this.value;
        this.value = this.get(); // 重新获取值
        this.cb.call(this.vm, this.value, oldValue); // 执行回调
      }
    }
  2. 依赖管理(Dep 类)
    每个响应式数据属性都有一个 Dep 实例,用于管理依赖。

    class Dep {
      constructor() {
        this.subs = []; // 存储 Watcher 实例
      }
    
      depend() {
        if (Dep.target) {
          this.subs.push(Dep.target); // 收集依赖
        }
      }
    
      notify() {
        this.subs.forEach(watcher => watcher.update()); // 通知更新
      }
    }

深度监听和立即执行

  1. 深度监听(deep: true)
    通过递归遍历对象的所有属性,为每个子属性绑定 Watcher

    vue watch 实现 原理

    if (this.deep) {
      traverse(value); // 递归触发子属性的 getter
    }
  2. 立即执行(immediate: true)
    Watcher 初始化时直接调用回调。

    if (options.immediate) {
      cb.call(vm, this.value);
    }

Vue 3 的改进

Vue 3 使用 Proxy 替代 Object.defineProperty,解决了以下问题:

  • 无需递归劫持对象,Proxy 可以动态监听新增属性。
  • 性能更好,避免了 Vue 2 中全量递归的缺陷。

总结

Vue 的 watch 机制依赖于响应式系统的核心设计:

  • 通过 WatcherDep 管理依赖关系。
  • 数据变化时触发 Watcher 回调。
  • 支持深度监听和立即执行等高级功能。

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

相关文章

vue实现签约合作弹窗

vue实现签约合作弹窗

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

vue实现后退

vue实现后退

Vue 实现后退功能的方法 在 Vue 中实现后退功能通常可以通过以下几种方式完成,具体取决于应用场景和需求。 使用 window.history API 通过原生 JavaScript 的 wi…

vue树形实现

vue树形实现

Vue 树形组件实现方法 使用递归组件实现树形结构 递归组件是 Vue 中实现树形结构的常见方法。通过组件调用自身的方式,可以轻松构建多层嵌套的树形结构。 <template> &l…

vue实现bootstrap

vue实现bootstrap

Vue 中集成 Bootstrap 的方法 在 Vue 项目中集成 Bootstrap 可以通过以下方式实现,涵盖样式、组件和交互功能。 安装 Bootstrap 依赖 通过 npm 或 yarn…

vue 实现滚动

vue 实现滚动

实现滚动的基本方法 在Vue中实现滚动效果可以通过多种方式完成,包括使用原生JavaScript、CSS或第三方库。以下是一些常见的方法: 使用window.scrollTo方法实现页面滚动 可以通…

vue实现拍照

vue实现拍照

Vue实现拍照功能 在Vue中实现拍照功能通常需要结合浏览器的MediaDevices API和Canvas元素。以下是具体实现方法: 安装依赖(可选) 如果需要更简单的封装,可以安装vue-web…