当前位置:首页 > VUE

vue observer实现

2026-01-12 21:55:32VUE

Vue Observer 实现原理

Vue 的响应式系统核心是通过 Observer 实现的,它利用 Object.defineProperty(Vue 2.x)或 Proxy(Vue 3.x)来劫持数据的变化,触发依赖更新。

Vue 2.x 的实现

在 Vue 2.x 中,Observer 通过递归遍历对象的属性,将其转换为响应式数据:

class Observer {
  constructor(value) {
    this.value = value;
    this.dep = new Dep(); // 依赖收集器
    def(value, '__ob__', this); // 标记为已观测
    if (Array.isArray(value)) {
      this.observeArray(value);
    } else {
      this.walk(value);
    }
  }

  walk(obj) {
    const keys = Object.keys(obj);
    for (let i = 0; i < keys.length; i++) {
      defineReactive(obj, keys[i]);
    }
  }

  observeArray(items) {
    for (let i = 0, l = items.length; i < l; i++) {
      observe(items[i]);
    }
  }
}

function defineReactive(obj, key, val) {
  if (arguments.length === 2) {
    val = obj[key];
  }
  const dep = new Dep();
  let childOb = observe(val); // 递归观测子属性
  Object.defineProperty(obj, key, {
    enumerable: true,
    configurable: true,
    get() {
      if (Dep.target) {
        dep.depend(); // 收集依赖
        if (childOb) {
          childOb.dep.depend();
        }
      }
      return val;
    },
    set(newVal) {
      if (val === newVal) return;
      val = newVal;
      childOb = observe(newVal); // 新值也可能是对象,需重新观测
      dep.notify(); // 通知更新
    }
  });
}

function observe(value) {
  if (!value || typeof value !== 'object') return;
  let ob;
  if (value.hasOwnProperty('__ob__') && value.__ob__ instanceof Observer) {
    ob = value.__ob__;
  } else {
    ob = new Observer(value);
  }
  return ob;
}

Vue 3.x 的实现

Vue 3.x 改用 Proxy 实现响应式,解决了 Vue 2.x 中无法检测数组和对象新增属性的问题:

function reactive(target) {
  const handler = {
    get(target, key, receiver) {
      track(target, key); // 依赖收集
      return Reflect.get(target, key, receiver);
    },
    set(target, key, value, receiver) {
      const oldValue = target[key];
      const result = Reflect.set(target, key, value, receiver);
      if (oldValue !== value) {
        trigger(target, key); // 触发更新
      }
      return result;
    }
  };
  return new Proxy(target, handler);
}

function track(target, key) {
  // 收集当前活跃的 effect(副作用函数)
  if (activeEffect) {
    let depsMap = targetMap.get(target);
    if (!depsMap) {
      targetMap.set(target, (depsMap = new Map()));
    }
    let dep = depsMap.get(key);
    if (!dep) {
      depsMap.set(key, (dep = new Set()));
    }
    dep.add(activeEffect);
  }
}

function trigger(target, key) {
  const depsMap = targetMap.get(target);
  if (!depsMap) return;
  const effects = depsMap.get(key);
  effects && effects.forEach(effect => effect());
}

核心差异

  • Vue 2.x:基于 Object.defineProperty,需递归遍历对象属性,无法检测新增/删除属性,需通过 Vue.setVue.delete 处理。
  • Vue 3.x:基于 Proxy,支持动态属性增删,性能更好,但需注意浏览器兼容性(IE 不支持)。

vue observer实现

标签: vueobserver
分享给朋友:

相关文章

vue设计与实现下载

vue设计与实现下载

vue设计与实现电子书下载 《Vue.js设计与实现》是一本深入解析Vue.js框架原理的书籍,由霍春阳(HcySunYang)撰写。以下是获取该资源的常见途径: 正版购买渠道 京东、…

vue实现a

vue实现a

Vue 实现 A 功能的方法 在 Vue 中实现 A 功能可以通过多种方式,具体取决于 A 功能的具体需求。以下是几种常见的实现方法: 使用 Vue 组件 通过创建自定义组件来实现 A 功能。组件…

vue实现图库

vue实现图库

Vue 实现图库的基本方法 使用 Vue 实现图库功能可以通过多种方式完成,以下是一些常见的方法和实现步骤。 使用 Vue 和第三方库(如 Vue Gallery) 安装 vue-gallery 或…

vue实现muli

vue实现muli

Vue 实现多语言(i18n)支持 在 Vue 项目中实现多语言(i18n)功能,通常使用 vue-i18n 插件。以下是具体实现步骤: 安装 vue-i18n npm install vue-i…

vue插槽实现

vue插槽实现

插槽的基本概念 Vue插槽(Slot)是一种内容分发机制,允许父组件向子组件传递模板片段,子组件通过<slot>标签定义接收位置。插槽的核心作用是增强组件的灵活性和复用性。 默认插槽 子…

vue实现引导

vue实现引导

Vue 实现引导功能的方法 使用第三方库 推荐使用 driver.js 或 intro.js 这类专门为 Vue 设计的引导库。这些库提供了完整的 API 和样式,能够快速实现引导功能。 安装 dr…