You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue reactive响应式原理解析及原生JavaScript实现方案

对,这确实是观察者模式的典型应用,Vue的响应式机制就是基于这个模式结合ES6的Proxy能力实现的。

Vue reactive 响应式机制的工作原理

Vue 3 的 reactive 函数核心逻辑可以拆成三个关键步骤:

  • Proxy 代理拦截:reactive 会用 Proxy 对传入的原始对象做一层包装,拦截对象所有属性的**读取(get)和修改(set)**操作。比如你访问 store.gender 时触发get拦截器,修改它时触发set拦截器。
  • 依赖自动收集:当组件渲染时,会读取store里的属性,此时get拦截器会把当前组件的渲染函数(或者更新逻辑)记录为该属性的“依赖”,存到对应的依赖集合里。
  • 触发更新通知:当你修改store的属性值时,set拦截器会检查值是否真的变化,然后遍历该属性对应的所有依赖,调用这些依赖函数,让所有用到这个属性的组件重新渲染——这就是为什么Navigation组件会同步更新数据。
原生JavaScript实现同款响应式Store

我们可以手动用Proxy+观察者模式实现相同功能,核心是管理订阅者和触发通知:

// 简易响应式Store实现
class ReactiveStore {
  constructor(initialState) {
    // 存储订阅关系:key是属性名,value是订阅该属性的回调数组
    this.subscribers = new Map();
    // 用Proxy代理初始状态,拦截读写
    this.state = new Proxy(initialState, {
      get: (target, prop) => {
        // 如果当前有正在执行的订阅回调,自动收集到对应属性的订阅列表
        if (ReactiveStore.currentSubscriber) {
          if (!this.subscribers.has(prop)) {
            this.subscribers.set(prop, []);
          }
          this.subscribers.get(prop).push(ReactiveStore.currentSubscriber);
        }
        return target[prop];
      },
      set: (target, prop, value) => {
        // 只有值真正变化时才触发更新
        if (target[prop] !== value) {
          target[prop] = value;
          // 通知所有订阅该属性的回调
          if (this.subscribers.has(prop)) {
            this.subscribers.get(prop).forEach(callback => callback());
          }
        }
        return true;
      }
    });
  }

  // 手动订阅属性变化,传入更新回调
  subscribe(prop, callback) {
    if (!this.subscribers.has(prop)) {
      this.subscribers.set(prop, []);
    }
    this.subscribers.get(prop).push(callback);
    // 立即执行一次回调,同步初始值
    callback();
  }

  // 静态变量,临时存储当前正在执行的订阅回调(用于自动收集依赖)
  static currentSubscriber = null;
}

// 使用示例
const store = new ReactiveStore({
  gender: "",
  name: ""
});

// 模拟Navigation组件订阅数据更新
store.subscribe('gender', () => {
  console.log('Navigation组件更新gender:', store.state.gender);
});
store.subscribe('name', () => {
  console.log('Navigation组件更新name:', store.state.name);
});

// 模拟RouterView修改数据
store.state.gender = 'male';
store.state.name = 'Max';

实现说明

  • 自动依赖收集:通过ReactiveStore.currentSubscriber静态变量,我们可以在组件渲染前把渲染函数赋值给它,这样组件读取store属性时就会自动被收集为依赖,不需要手动调用subscribe。
  • 更新触发:当属性值变化时,set拦截器会遍历对应订阅列表,调用所有回调函数,实现所有订阅组件的同步更新。

内容的提问来源于stack exchange,提问作者Max Pattern

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 20:35:16