当前位置:首页 > VUE

vue observer实现

2026-01-07 20:12:38VUE

Vue Observer 实现原理

Vue 的响应式系统核心是通过 Object.defineProperty(Vue 2)或 Proxy(Vue 3)实现的 Observer 模式。以下是关键实现细节:

数据劫持(Vue 2)

通过 Object.defineProperty 递归地将对象的属性转换为 getter/setter:

vue observer实现

function defineReactive(obj, key, val) {
  Object.defineProperty(obj, key, {
    enumerable: true,
    configurable: true,
    get() {
      console.log(`读取 ${key}`);
      return val;
    },
    set(newVal) {
      if (val === newVal) return;
      console.log(`更新 ${key}`);
      val = newVal;
    }
  });
}

依赖收集与触发

  1. 依赖收集:在 getter 中通过 Dep 类收集依赖(Watcher):

    class Dep {
    constructor() {
     this.subscribers = [];
    }
    depend() {
     if (target && !this.subscribers.includes(target)) {
       this.subscribers.push(target);
     }
    }
    notify() {
     this.subscribers.forEach(sub => sub());
    }
    }
  2. 触发更新:在 setter 中通知依赖更新:

    vue observer实现

    set(newVal) {
    if (val === newVal) return;
    val = newVal;
    dep.notify(); // 触发所有依赖的 Watcher
    }

数组响应式处理(Vue 2)

重写数组的变异方法(如 push/pop):

const arrayProto = Array.prototype;
const arrayMethods = Object.create(arrayProto);
['push', 'pop'].forEach(method => {
  const original = arrayProto[method];
  arrayMethods[method] = function(...args) {
    const result = original.apply(this, args);
    dep.notify(); // 手动触发更新
    return result;
  };
});

Proxy 实现(Vue 3)

使用 Proxy 替代 Object.defineProperty

function reactive(obj) {
  return new Proxy(obj, {
    get(target, key) {
      track(target, key); // 依赖收集
      return Reflect.get(target, key);
    },
    set(target, key, value) {
      Reflect.set(target, key, value);
      trigger(target, key); // 触发更新
    }
  });
}

关键点总结

  • 递归劫持:Vue 2 需递归遍历对象的所有属性。
  • 性能优化:Vue 3 的 Proxy 无需递归,按需响应。
  • 数组处理:Vue 2 需特殊处理数组方法,Vue 3 的 Proxy 天然支持。

通过上述机制,Vue 实现了数据变化到视图更新的自动响应。

标签: vueobserver
分享给朋友:

相关文章

vue实现分支

vue实现分支

Vue 实现分支的方法 在 Vue 项目中实现分支功能通常涉及条件渲染、动态组件或路由控制。以下是几种常见的实现方式: 条件渲染(v-if/v-show) 使用 Vue 的指令根据条件显示不同内容:…

vue实现文档

vue实现文档

Vue 实现文档的方法 在 Vue 中实现文档功能可以通过多种方式,包括使用富文本编辑器、Markdown 解析或直接渲染 HTML。以下是几种常见的实现方法。 使用富文本编辑器 富文本编辑器如…

vue循环数组实现

vue循环数组实现

vue循环数组的实现方法 在Vue中循环数组主要通过v-for指令实现,以下是几种常见用法: 基本数组循环 使用v-for指令遍历数组,可以通过(item, index)的语法获取当前项和索引值:…

vue实现多选联动

vue实现多选联动

vue实现多选联动的方法 使用v-model绑定数组 在Vue中,可以通过v-model绑定一个数组来实现多选联动。当复选框被选中或取消选中时,数组会自动更新。 <template>…

vue实现屏幕共享

vue实现屏幕共享

Vue 实现屏幕共享的方法 使用 WebRTC 和 getDisplayMedia API 通过 navigator.mediaDevices.getDisplayMedia 捕获屏幕内容,结合 We…

vue实现菜单调用

vue实现菜单调用

Vue 实现动态菜单的常见方法 基于路由配置生成菜单 Vue Router 的路由配置可以天然转化为菜单结构,适合权限与路由绑定的系统: // router/index.js const route…