当前位置:首页 > VUE

实现vue中的watcher

2026-02-22 04:33:05VUE

Vue 中的 Watcher 实现

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

创建 Watcher 类

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

实现vue中的watcher

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')转换为访问对象属性的函数。

实现vue中的watcher

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 的核心功能,监听数据变化并触发回调。

标签: vuewatcher
分享给朋友:

相关文章

vue 实现目录

vue 实现目录

Vue 实现目录的方法 在 Vue 项目中实现目录功能,可以通过以下几种方式实现,具体取决于需求和技术栈。 使用 Vue Router 实现路由目录 Vue Router 是 Vue.js 的官方路…

vue实现录音文件播放

vue实现录音文件播放

使用 Vue 实现录音文件播放 准备工作 确保项目中已安装必要的依赖,如 vue-audio-recorder 或原生 Web Audio API。录音文件播放通常涉及录音、存储和播放三个核心环节。…

vue实现字母添加排序

vue实现字母添加排序

实现字母添加排序的方法 在Vue中实现字母添加排序功能,可以通过以下步骤完成: 创建Vue实例并定义数据 new Vue({ el: '#app', data: { letters…

vue怎么实现

vue怎么实现

Vue 实现方法 Vue 是一个流行的前端框架,用于构建用户界面。以下是几种常见的实现方法: 数据绑定 使用 v-model 指令实现双向数据绑定,适用于表单输入元素。 <input v-m…

vue实现海报

vue实现海报

Vue 实现海报生成方案 使用 html2canvas 库 html2canvas 是一个将 HTML 元素转换为 Canvas 的库,适合将 Vue 组件渲染为海报图片 安装依赖: npm in…

vue实现标题

vue实现标题

Vue 实现标题的方法 在Vue中实现标题可以通过多种方式,以下是几种常见的方法: 方法一:使用模板语法 在Vue组件的模板中直接使用HTML的<h1>到<h6>标签来定义…