当前位置:首页 > 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实现图片轮播

使用 Swiper 实现图片轮播 安装 Swiper 依赖 npm install swiper 在 Vue 组件中引入 Swiper <template> <div…

vue实现静态查询

vue实现静态查询

Vue 实现静态查询 在 Vue 中实现静态查询通常指不依赖后端接口,直接在前端处理数据筛选或搜索功能。以下是几种常见实现方式: 使用计算属性过滤数据 通过计算属性对静态数据进行筛选,适合简单查询…

vue实现屏幕共享

vue实现屏幕共享

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

vue实现tab换行

vue实现tab换行

Vue实现Tab切换的常见方法 使用Vue实现Tab切换功能可以通过多种方式完成,以下是几种常见的方法: 动态组件结合v-if或v-show 通过v-if或v-show控制不同Tab内容的显示与隐…

vue卖座网实现

vue卖座网实现

Vue 卖座网实现 项目结构搭建 使用 Vue CLI 快速初始化项目,安装必要依赖如 Vue Router、Vuex、Axios。 创建核心目录结构:components(通用组件)、views(页…

vue为啥能实现监听

vue为啥能实现监听

Vue 实现监听的原理 Vue 的监听能力主要基于其响应式系统,该系统通过数据劫持和依赖收集实现。当数据变化时,系统能自动触发视图更新或执行回调函数。 核心机制:Object.defineProp…