当前位置:首页 > VUE

vue observer实现

2026-02-10 05:11:26VUE

Vue Observer 实现原理

Vue 的响应式系统核心是通过 Object.definePropertyProxy 实现的 Observer 模式。以下是关键实现细节:

数据劫持

通过 Object.defineProperty 对对象属性进行劫持(Vue 2.x):

function defineReactive(obj, key, val) {
  Object.defineProperty(obj, key, {
    get() {
      console.log(`读取 ${key}`);
      return val;
    },
    set(newVal) {
      if (newVal === val) return;
      console.log(`设置 ${key} 为 ${newVal}`);
      val = newVal;
    }
  });
}

Vue 3.x 改用 Proxy 实现:

const reactive = (target) => {
  return new Proxy(target, {
    get(target, key, receiver) {
      track(target, key);
      return Reflect.get(target, key, receiver);
    },
    set(target, key, value, receiver) {
      trigger(target, key);
      return Reflect.set(target, key, value, receiver);
    }
  });
};

依赖收集

每个被观察的属性都有一个 Dep 实例,用于存储所有依赖(Watcher):

class Dep {
  constructor() {
    this.subscribers = new Set();
  }
  depend() {
    if (activeEffect) {
      this.subscribers.add(activeEffect);
    }
  }
  notify() {
    this.subscribers.forEach(effect => effect());
  }
}

观察者模式

通过 Watcher 建立观察者:

let activeEffect = null;
function watchEffect(effect) {
  activeEffect = effect;
  effect();
  activeEffect = null;
}

数组处理

Vue 对数组方法进行特殊处理(Vue 2.x):

const arrayProto = Array.prototype;
const arrayMethods = Object.create(arrayProto);
['push', 'pop', 'shift', 'unshift'].forEach(method => {
  const original = arrayProto[method];
  arrayMethods[method] = function(...args) {
    const result = original.apply(this, args);
    dep.notify();
    return result;
  };
});

实现示例

完整的最小化实现示例:

vue observer实现

class Dep {
  constructor() { this.subscribers = new Set(); }
  depend() { if (activeEffect) this.subscribers.add(activeEffect); }
  notify() { this.subscribers.forEach(effect => effect()); }
}

function reactive(obj) {
  Object.keys(obj).forEach(key => {
    const dep = new Dep();
    let value = obj[key];
    Object.defineProperty(obj, key, {
      get() {
        dep.depend();
        return value;
      },
      set(newValue) {
        if (newValue !== value) {
          value = newValue;
          dep.notify();
        }
      }
    });
  });
  return obj;
}

let activeEffect = null;
function watchEffect(effect) {
  activeEffect = effect;
  effect();
  activeEffect = null;
}

// 使用示例
const state = reactive({ count: 0 });
watchEffect(() => {
  console.log(`count: ${state.count}`);
});
state.count++; // 触发重新执行

性能优化

  • 避免深层嵌套对象的全量观察
  • 采用懒观察策略(Lazy Observation)
  • 对不可变数据使用 Object.freeze 跳过响应式处理
  • Vue 3 的 Proxy 实现比 Vue 2 的 defineProperty 有更好的性能表现

以上实现展示了 Vue 响应式系统的核心机制,实际源码中还包含更多边界条件处理和优化策略。

标签: vueobserver
分享给朋友:

相关文章

vue实现骰子

vue实现骰子

Vue 实现骰子功能 创建 Vue 组件 在 Vue 项目中创建一个骰子组件,例如 Dice.vue。该组件包含骰子的外观和逻辑。 <template> <div class=…

vue 实现轮播

vue 实现轮播

Vue 实现轮播的方法 使用第三方库(如 Swiper) 安装 Swiper 库: npm install swiper 在 Vue 组件中引入 Swiper: <template&…

甘特图vue实现

甘特图vue实现

甘特图 Vue 实现方法 使用开源库 vue-ganttastic 安装依赖: npm install vue-ganttastic 基础实现代码: <template> <…

vue多选实现

vue多选实现

Vue 多选实现方法 基础实现(v-model + multiple) 在 Vue 中实现多选可以通过 <select> 元素的 multiple 属性结合 v-model 完成。v-mo…

vue 实现登录

vue 实现登录

Vue 实现登录功能 创建登录表单组件 在 Vue 项目中创建一个登录表单组件(如 Login.vue),包含用户名和密码输入框以及提交按钮。使用 v-model 实现双向数据绑定。 <tem…

vue实现vmodel

vue实现vmodel

Vue 实现 v-model Vue 的 v-model 是一个语法糖,用于在表单元素或组件上实现双向数据绑定。以下是其实现方式和原理的详细说明。 在表单元素上使用 v-model v-model…