当前位置:首页 > 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 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

    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 watch 实现 原理

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

相关文章

vue实现检测数组

vue实现检测数组

Vue 中检测数组变化的方法 Vue 的响应式系统无法直接检测到数组的某些变化,因为 JavaScript 的限制。以下是一些解决方案: 使用 Vue.set 或 this.$set Vue…

vue实现sql操作

vue实现sql操作

在Vue中实现SQL操作通常需要结合后端服务或本地数据库技术,因为前端JavaScript无法直接连接SQL数据库。以下是几种常见的实现方式: 通过API与后端交互 Vue前端通过HTTP请求(如a…

vue实现网页切换

vue实现网页切换

Vue 实现网页切换的方法 在 Vue 中实现网页切换通常可以通过以下几种方式完成,具体取决于项目需求和路由管理方式。 使用 Vue Router Vue Router 是 Vue.js 官方提供…

vue前端实现搜索

vue前端实现搜索

实现搜索功能的基本方法 在Vue中实现搜索功能通常涉及以下几个关键步骤,结合数据绑定、计算属性和方法调用来动态过滤和显示结果。 数据绑定与输入处理 使用v-model双向绑定搜索输入框的值,监听用…

vue核心实现原理详解

vue核心实现原理详解

Vue核心实现原理 Vue.js的核心实现原理主要包括响应式系统、虚拟DOM、模板编译和组件化机制。以下是对这些核心原理的详细解析: 响应式系统 Vue的响应式系统基于Object.definePr…

vue实现按钮组轮换

vue实现按钮组轮换

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