当前位置:首页 > VUE

vue observer实现

2026-01-12 21:55:32VUE

Vue Observer 实现原理

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

vue observer实现

Vue 2.x 的实现

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

vue 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 不支持)。

标签: vueobserver
分享给朋友:

相关文章

vue实现上移下移插件

vue实现上移下移插件

实现上移下移功能的 Vue 插件 在 Vue 中实现列表项的上移和下移功能,可以通过自定义指令或组件封装的方式完成。以下是两种常见实现方式: 基于数组操作的通用方法 通过操作数组索引实现元素位置交换…

vue树形实现

vue树形实现

Vue 树形组件实现方法 使用递归组件实现树形结构 递归组件是 Vue 中实现树形结构的常见方法。通过组件调用自身的方式,可以轻松构建多层嵌套的树形结构。 <template> &l…

vue 实现滚动

vue 实现滚动

实现滚动的基本方法 在Vue中实现滚动效果可以通过多种方式完成,包括使用原生JavaScript、CSS或第三方库。以下是一些常见的方法: 使用window.scrollTo方法实现页面滚动 可以通…

vue实现剪辑

vue实现剪辑

Vue 实现视频剪辑功能 在Vue中实现视频剪辑功能通常需要结合HTML5的<video>元素和第三方库(如FFmpeg.js或Video.js)。以下是几种常见的实现方法: 使用FFm…

vue 实现过滤

vue 实现过滤

Vue 实现过滤的方法 在 Vue 中实现过滤功能可以通过多种方式完成,包括使用计算属性、自定义过滤器、第三方库等。以下是几种常见的实现方法: 使用计算属性进行过滤 计算属性是 Vue 中最常用的过…

vue 动画实现

vue 动画实现

Vue 动画实现方式 Vue 提供了多种方式实现动画效果,主要分为内置组件和第三方库集成。 使用 Vue 内置过渡组件 Vue 的 <transition> 和 <transiti…