当前位置:首页 > VUE

实现vue中的watcher

2026-02-22 04:33:05VUE

Vue 中的 Watcher 实现

在 Vue 中,Watcher 是响应式系统的核心组件之一,用于监听数据变化并执行回调。以下是实现 Watcher 的关键方法和步骤。

创建 Watcher 类

Watcher 类需要接收 Vue 实例、要监听的表达式(或函数)以及回调函数。初始化时会进行依赖收集。

class Watcher {
  constructor(vm, expOrFn, cb) {
    this.vm = vm;
    this.cb = cb;
    this.getter = parsePath(expOrFn); // 解析表达式为函数
    this.value = this.get(); // 初始化时触发依赖收集
  }

  get() {
    Dep.target = this; // 设置当前 Watcher 为全局目标
    const value = this.getter.call(this.vm, this.vm); // 触发属性的 getter
    Dep.target = null; // 收集完成后清除目标
    return value;
  }

  update() {
    const oldValue = this.value;
    this.value = this.get(); // 重新获取值
    this.cb.call(this.vm, this.value, oldValue); // 执行回调
  }
}

解析表达式

parsePath 用于将字符串路径(如 'a.b.c')转换为访问对象属性的函数。

function parsePath(path) {
  const segments = path.split('.');
  return function (obj) {
    for (let i = 0; i < segments.length; i++) {
      if (!obj) return;
      obj = obj[segments[i]];
    }
    return obj;
  };
}

依赖收集与触发

依赖收集通过 Dep 类实现,每个响应式属性会关联一个 Dep 实例。

class Dep {
  constructor() {
    this.subs = []; // 存储 Watcher 实例
  }

  addSub(sub) {
    this.subs.push(sub);
  }

  notify() {
    this.subs.forEach(sub => sub.update()); // 通知所有 Watcher 更新
  }
}

// 在响应式属性的 getter 中收集依赖
function defineReactive(obj, key, val) {
  const dep = new Dep();
  Object.defineProperty(obj, key, {
    enumerable: true,
    configurable: true,
    get: function reactiveGetter() {
      if (Dep.target) {
        dep.addSub(Dep.target); // 将当前 Watcher 添加到依赖列表
      }
      return val;
    },
    set: function reactiveSetter(newVal) {
      if (newVal === val) return;
      val = newVal;
      dep.notify(); // 触发更新
    }
  });
}

示例使用

以下是如何在 Vue 实例中使用自定义 Watcher 监听数据变化。

const vm = { a: { b: 1 } };
defineReactive(vm.a, 'b', vm.a.b); // 使属性响应式

new Watcher(vm, 'a.b', (newVal, oldVal) => {
  console.log(`值从 ${oldVal} 变为 ${newVal}`);
});

vm.a.b = 2; // 输出: "值从 1 变为 2"

注意事项

  1. 性能优化:避免过度使用 Watcher,复杂逻辑可改用计算属性。
  2. 深层监听:对于嵌套对象,需递归调用 defineReactive
  3. 异步更新:Vue 实际实现中会将 Watcher 推入队列异步更新,避免重复计算。

通过以上步骤,可以实现 Vue 中 Watcher 的核心功能,监听数据变化并触发回调。

实现vue中的watcher

标签: vuewatcher
分享给朋友:

相关文章

vue请求实现进度条

vue请求实现进度条

实现请求进度条的方法 在Vue中实现请求进度条可以通过多种方式完成,常见的有使用第三方库如axios结合nprogress或自定义进度条组件。以下是几种实现方法: 使用axios和nprogres…

vue菜单实现

vue菜单实现

Vue 菜单实现方法 使用 Element UI 的菜单组件 Element UI 提供了现成的菜单组件,适合快速实现导航菜单。安装 Element UI 后,可以直接使用 el-menu 相关组件。…

vue实现复选

vue实现复选

Vue 实现复选框 在 Vue 中实现复选框可以通过 v-model 指令绑定数据,同时结合 input 元素的 type="checkbox" 属性来实现。以下是几种常见的实现方式: 单个复选框…

vue能实现

vue能实现

Vue.js 是一个流行的前端框架,能够实现多种功能。以下是 Vue 能够实现的主要功能和特性: 响应式数据绑定 Vue 的核心特性之一是响应式数据绑定。通过数据驱动视图,当数据发生变化时,视图会…

vue实现frame

vue实现frame

Vue 中实现 iframe 的方法 在 Vue 中可以通过直接使用 <iframe> 标签或动态绑定 src 属性来实现 iframe 功能。 基本用法 <template…

vue实现driver

vue实现driver

Vue 实现 Driver.js 引导功能 Driver.js 是一个轻量级的 JavaScript 库,用于在网页上创建引导式导览。以下是在 Vue 项目中集成 Driver.js 的详细方法:…