参考链接: [微前端][vue3 + vite + qiankun] 使用详解

一般来说,各个子应用是通过业务来划分的,不同业务线应该降低耦合度,尽量去避免通信,但是如果涉及到一些公共的状态或者操作,qiankun也是支持的。

qinkun提供了一个全局的GlobalState来共享数据,基座初始化之后,子应用可以监听到这个数据的变化,也能提交这个数据。

假设有如下一个具体的业务场景:有一个基座应用(主应用)和多个子应用(微前端应用)。我们假设有一个全局的用户信息状态(例如用户ID、用户名、权限等)需要在基座和所有子应用之间共享。当用户在基座应用中登录后,用户信息需要传递给所有子应用,同时子应用可能在某些操作后更新用户信息(例如更新用户昵称),并且其他子应用和基座需要响应这个更新。

步骤

  1. 基座应用初始化全局状态,包括用户信息。
  2. 基座应用在启动qiankun时,将全局状态传递给子应用。
  3. 子应用可以监听全局状态的变化,并在状态变化时更新自己的界面。
  4. 子应用也可以修改全局状态,并通知到基座和其他子应用。

具体实现

基座应用(主应用):

  1. 使用qiankun的initGlobalState方法初始化全局状态。
  2. 注册子应用,并将全局状态传递给子应用。
  3. 监听全局状态的变化,以便在基座中更新。

多个子应用需要共享用户登录状态、用户信息和权限数据,避免重复登录和权限校验。

// 主应用 - 初始化全局状态
import { initGlobalState } from 'qiankun';

// 初始化状态
const initialState = {
  user: {
    id: null,
    name: '',
    avatar: '',
    roles: [],
    permissions: []
  },
  token: '',
  isLoggedIn: false
};

const actions = initGlobalState(initialState);

// 用户登录后更新状态
actions.setGlobalState({
  user: {
    id: 12345,
    name: '张三',
    avatar: '/avatars/zhangsan.jpg',
    roles: ['admin', 'user'],
    permissions: ['read', 'write', 'delete']
  },
  token: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...',
  isLoggedIn: true
});

// 监听登录状态变化
actions.onGlobalStateChange((state, prevState) => {
  // 主应用自身的状态同步
  if (state.isLoggedIn !== prevState.isLoggedIn) {
    console.log('登录状态变化:', state.isLoggedIn);
    updateMainAppUI(state);
  }
});

子应用:

  1. 在生命周期函数中,获取基座传递的全局状态,并监听状态变化。
  2. 在适当的时候(例如用户操作后)使用setGlobalState更新全局状态。
let globalAction = null;

// 子应用A - 用户管理
export async function mount(props) {
  // 保存全局状态操作对象
  globalAction = props;

  // 监听全局状态变化
  props.onGlobalStateChange((state, prevState) => {
    // 用户信息变化时更新界面
    if (state.user.id !== prevState.user.id) {
      updateUserProfile(state.user);
    }
    
    // 权限变化时重新检查
    if (state.user.permissions !== prevState.user.permissions) {
      checkPermissions(state.user.permissions);
    }
  }, true); // 立即执行一次
  
  // 渲染子应用
  renderApp(props);
}

  // 更新用户信息
  const updateUserInfo = (newUserInfo) => {
    globalAction.setGlobalState({
      user: {
        ...globalAction.getGlobalState().user,
        ...newUserInfo
      }
    });
  };
  
  // 检查权限
  const checkPermissions = (requiredPermission) => {
    const { permissions } = globalAction.getGlobalState().user;
    return permissions.includes(requiredPermission);
  };
  

原理

qiankun 的 initGlobalState 方法提供了一种在微前端架构中主应用与子应用之间通信的机制。其原理主要基于以下步骤:

状态初始化:主应用调用 initGlobalState 初始化全局状态,并返回一个对象,该对象包含设置状态、监听状态变化等方法。

状态存储:全局状态被存储在一个中心化的地方,并且可以被多个子应用访问。

状态更新:当主应用或子应用调用 setGlobalState 更新状态时,会触发所有已经注册的监听器(包括主应用和子应用)。

状态监听:子应用(或主应用)可以通过 onGlobalStateChange 注册监听函数,当全局状态发生变化时,会执行这些监听函数。

状态隔离:qiankun 会确保每个子应用都能独立地监听全局状态,并且不会互相干扰。

下面是一个简化的实现原理示例,帮助理解 qiankun 的全局状态管理:

// 模拟 qiankun 的全局状态管理
let globalState = {}; // 全局状态
let listeners = [];   // 监听器列表

function initGlobalState(initialState = {}) {
  // 合并初始状态
  globalState = { ...globalState, ...initialState };

  // 返回一个对象,包含操作全局状态的方法
  return {
    // 设置全局状态
    setGlobalState(state) {
      const prevState = { ...globalState };
      globalState = { ...globalState, ...state };
      // 通知所有监听器
      listeners.forEach(listener => {
        listener(globalState, prevState);
      });
    },

    // 监听全局状态变化
    onGlobalStateChange(listener, immediate = false) {
      listeners.push(listener);
      // 如果立即执行,则立即调用一次监听器
      if (immediate) {
        listener(globalState, globalState);
      }
      // 返回一个取消监听的函数
      return () => {
        const index = listeners.indexOf(listener);
        if (index > -1) {
          listeners.splice(index, 1);
        }
      };
    },

    // 获取当前全局状态
    getGlobalState() {
      return globalState;
    },

    // 移除所有监听器(通常用于应用卸载时)
    offGlobalStateChange() {
      listeners = [];
    }
  };
}

// 主应用使用
const actions = initGlobalState({ user: 'main' });

// 子应用使用
// 假设子应用通过某种方式获取到 actions(通常是通过 props 传递)
// 子应用监听状态变化
const unsubscribe = actions.onGlobalStateChange((state, prevState) => {
  console.log('子应用监听到状态变化', state, prevState);
}, true);

// 子应用更新状态
actions.setGlobalState({ user: 'subapp' });

// 取消监听
// unsubscribe();

在实际的 qiankun 实现中,还会考虑以下方面:

状态隔离:确保子应用在卸载时自动取消监听,避免内存泄漏。

状态同步:当子应用初始化时,能够获取到最新的全局状态。

多实例支持:在多个子应用同时运行时,每个子应用都可以独立地监听和更新状态。

在 qiankun 的源码中,全局状态的管理是在 src/globalState.ts 中实现的。它使用了类似发布-订阅的模式,并且通过一个全局的变量来存储状态。主应用和子应用通过这个全局的变量进行通信。

注意:在子应用中,qiankun 会通过生命周期函数的参数将全局状态的操作方法传递给子应用,子应用在挂载时可以通过 props 获取到这些方法。

例如,在主应用中注册子应用时:

import { registerMicroApps, start } from 'qiankun';

registerMicroApps([
  {
    name: 'subapp',
    entry: '//localhost:7100',
    container: '#subapp-container',
    activeRule: '/subapp',
    props: {
      // 传递全局状态操作方法
      onGlobalStateChange: actions.onGlobalStateChange,
      setGlobalState: actions.setGlobalState,
      getGlobalState: actions.getGlobalState,
    },
  },
]);

start();

在子应用中,在生命周期函数中接收:

export async function mount(props) {
  // 子应用可以使用 props 上的方法
  props.onGlobalStateChange((state, prev) => {
    // 状态变化时的操作
  });
  
  props.setGlobalState({ ... });
}

这样,主应用和子应用就可以通过这个全局状态进行通信了。

Qiankun initGlobalState 全局状态通信原理与实现

状态管理架构

Qiankun 的全局状态管理基于发布-订阅模式,采用中心化的状态存储和事件通知机制

// 简化的核心实现原理
class GlobalStateManager {
  constructor() {
    this.state = {};                    // 全局状态存储
    this.listeners = new Map();         // 监听器映射表
    this.subAppStates = new Map();      // 子应用状态快照
    this.isMainApp = true;              // 标识是否为主应用
  }

  // 初始化全局状态
  initGlobalState(initialState = {}) {
    this.state = { ...initialState };
    return this.createActions();
  }

  // 创建状态操作方法
  createActions() {
    return {
      setGlobalState: (state) => this.setGlobalState(state),
      onGlobalStateChange: (callback, immediately = false) => 
        this.onGlobalStateChange(callback, immediately),
      offGlobalStateChange: (callback) => this.offGlobalStateChange(callback),
      getGlobalState: () => this.getGlobalState()
    };
  }

  // 设置全局状态
  setGlobalState(state) {
    const prevState = { ...this.state };
    
    // 合并新状态
    this.state = {
      ...this.state,
      ...state
    };

    // 通知所有监听器
    this.notifyListeners(this.state, prevState);
    
    return true;
  }

  // 注册状态变化监听器
  onGlobalStateChange(callback, immediately = false) {
    const listenerId = Symbol('listener');
    
    this.listeners.set(listenerId, callback);
    
    // 立即执行一次
    if (immediately) {
      try {
        callback(this.state, this.state);
      } catch (error) {
        console.error('Global state listener error:', error);
      }
    }

    // 返回取消监听函数
    return () => {
      this.listeners.delete(listenerId);
    };
  }

  // 移除监听器
  offGlobalStateChange(callback) {
    for (const [id, listener] of this.listeners.entries()) {
      if (listener === callback) {
        this.listeners.delete(id);
        break;
      }
    }
  }

  // 获取当前状态
  getGlobalState() {
    return { ...this.state };
  }

  // 通知所有监听器
  notifyListeners(currentState, previousState) {
    this.listeners.forEach((listener, id) => {
      try {
        // 使用 setTimeout 确保异步执行,避免阻塞
        setTimeout(() => {
          if (this.listeners.has(id)) {
            listener(currentState, previousState);
          }
        }, 0);
      } catch (error) {
        console.error(`Listener ${id.toString()} error:`, error);
      }
    });
  }

  // 子应用挂载时的状态同步
  syncStateToSubApp(subAppName, actions) {
    // 保存子应用的状态操作引用
    this.subAppStates.set(subAppName, actions);
    
    // 返回子应用专用的状态操作对象
    return this.createSubAppActions(actions);
  }

  // 创建子应用专用的操作对象
  createSubAppActions(subAppActions) {
    return {
      ...subAppActions,
      // 可以在这里添加子应用特定的逻辑
      getSubAppState: () => this.getGlobalState()
    };
  }
}

完整实现源码解析

下面是更接近 Qiankun 实际实现的完整代码:

// globalState.js - Qiankun 全局状态管理核心实现
class GlobalState {
  constructor() {
    // 全局状态存储
    this.state = {};
    
    // 监听器存储:Map<symbol, Function>
    this.listeners = new Map();
    
    // 标识是否已初始化
    this.initialized = false;
    
    // 主应用标识
    this.isMaster = typeof window !== 'undefined' && 
                   window.__POWERED_BY_QIANKUN__ !== true;
  }

  /**
   * 初始化全局状态
   * @param {Object} initialState 初始状态
   * @returns {Object} 状态操作对象
   */
  initGlobalState(initialState = {}) {
    if (this.initialized) {
      console.warn('[qiankun] Global state already initialized');
      return this.getActions();
    }

    this.state = this.deepClone(initialState);
    this.initialized = true;

    // 在开发模式下打印日志
    if (process.env.NODE_ENV === 'development') {
      console.log('[qiankun] Global state initialized:', this.state);
    }

    return this.getActions();
  }

  /**
   * 获取状态操作对象
   */
  getActions() {
    return {
      setGlobalState: this.setGlobalState.bind(this),
      onGlobalStateChange: this.onGlobalStateChange.bind(this),
      offGlobalStateChange: this.offGlobalStateChange.bind(this),
      getGlobalState: this.getGlobalState.bind(this),
    };
  }

  /**
   * 设置全局状态
   * @param {Object} state 新状态
   * @param {boolean} overwrite 是否覆盖整个状态
   */
  setGlobalState(state, overwrite = false) {
    if (!this.initialized) {
      console.error('[qiankun] Global state not initialized');
      return false;
    }

    const prevState = this.deepClone(this.state);
    
    if (overwrite) {
      this.state = this.deepClone(state);
    } else {
      this.state = this.mergeState(this.state, state);
    }

    // 触发监听器
    this.emit(prevState);

    if (process.env.NODE_ENV === 'development') {
      console.log('[qiankun] Global state updated:', {
        from: prevState,
        to: this.state
      });
    }

    return true;
  }

  /**
   * 注册状态变化监听器
   * @param {Function} listener 监听函数
   * @param {boolean} fireImmediately 是否立即执行
   */
  onGlobalStateChange(listener, fireImmediately = false) {
    if (typeof listener !== 'function') {
      throw new Error('[qiankun] Listener must be a function');
    }

    const listenerId = Symbol('qiankun-global-state-listener');
    this.listeners.set(listenerId, listener);

    // 立即执行一次
    if (fireImmediately) {
      try {
        setTimeout(() => {
          if (this.listeners.has(listenerId)) {
            listener(this.state, this.state);
          }
        }, 0);
      } catch (error) {
        console.error('[qiankun] Fire immediately error:', error);
      }
    }

    // 返回取消监听函数
    return () => {
      this.listeners.delete(listenerId);
    };
  }

  /**
   * 移除状态变化监听器
   * @param {Function} listener 要移除的监听函数
   */
  offGlobalStateChange(listener) {
    for (const [id, fn] of this.listeners.entries()) {
      if (fn === listener) {
        this.listeners.delete(id);
        break;
      }
    }
  }

  /**
   * 获取当前全局状态
   */
  getGlobalState() {
    return this.deepClone(this.state);
  }

  /**
   * 触发所有监听器
   * @param {Object} prevState 之前的状态
   */
  emit(prevState) {
    const currentState = this.deepClone(this.state);
    
    this.listeners.forEach((listener, id) => {
      try {
        // 使用微任务异步执行,避免阻塞主线程
        Promise.resolve().then(() => {
          if (this.listeners.has(id)) {
            listener(currentState, prevState);
          }
        }).catch(error => {
          console.error(`[qiankun] Listener ${id.toString()} error:`, error);
        });
      } catch (error) {
        console.error(`[qiankun] Listener ${id.toString()} error:`, error);
      }
    });
  }

  /**
   * 深度合并状态
   * @param {Object} target 目标对象
   * @param {Object} source 源对象
   */
  mergeState(target, source) {
    const result = this.deepClone(target);
    
    for (const key in source) {
      if (source.hasOwnProperty(key)) {
        const sourceValue = source[key];
        const targetValue = result[key];
        
        if (this.isPlainObject(sourceValue) && this.isPlainObject(targetValue)) {
          // 递归合并对象
          result[key] = this.mergeState(targetValue, sourceValue);
        } else {
          // 直接赋值
          result[key] = this.deepClone(sourceValue);
        }
      }
    }
    
    return result;
  }

  /**
   * 深度克隆对象
   * @param {any} obj 要克隆的对象
   */
  deepClone(obj) {
    if (obj === null || typeof obj !== 'object') {
      return obj;
    }
    
    if (obj instanceof Date) {
      return new Date(obj.getTime());
    }
    
    if (obj instanceof Array) {
      return obj.map(item => this.deepClone(item));
    }
    
    if (typeof obj === 'object') {
      const clonedObj = {};
      for (const key in obj) {
        if (obj.hasOwnProperty(key)) {
          clonedObj[key] = this.deepClone(obj[key]);
        }
      }
      return clonedObj;
    }
  }

  /**
   * 判断是否为纯对象
   * @param {any} obj 要判断的对象
   */
  isPlainObject(obj) {
    return obj !== null && 
           typeof obj === 'object' && 
           Object.prototype.toString.call(obj) === '[object Object]';
  }

  /**
   * 销毁全局状态管理器
   */
  destroy() {
    this.state = {};
    this.listeners.clear();
    this.initialized = false;
  }
}

// 创建单例实例
let globalStateInstance = null;

function initGlobalState(initialState = {}) {
  if (!globalStateInstance) {
    globalStateInstance = new GlobalState();
  }
  
  return globalStateInstance.initGlobalState(initialState);
}

// 获取全局状态实例(用于调试)
function getGlobalStateInstance() {
  return globalStateInstance;
}

export { initGlobalState, getGlobalStateInstance };

主应用与子应用通信桥梁

主应用中的状态集成
// main-app/src/micro-fe/state-bridge.js
import { initGlobalState } from 'qiankun';

class MainAppStateBridge {
  constructor() {
    this.actions = null;
    this.subApps = new Map();
  }

  // 初始化全局状态
  init(initialState) {
    this.actions = initGlobalState(initialState);
    
    // 监听自身状态变化
    this.actions.onGlobalStateChange((state, prevState) => {
      this.handleMainAppStateChange(state, prevState);
    });
    
    return this.actions;
  }

  // 为子应用创建状态桥接
  createSubAppStateBridge(subAppName) {
    if (!this.actions) {
      throw new Error('Global state not initialized');
    }

    const subAppActions = {
      ...this.actions,
      // 子应用特定的方法
      getSubAppName: () => subAppName,
      // 可以添加子应用级别的状态管理
      setSubAppState: (state) => this.setSubAppState(subAppName, state)
    };

    this.subApps.set(subAppName, {
      actions: subAppActions,
      state: {}
    });

    return subAppActions;
  }

  // 处理主应用状态变化
  handleMainAppStateChange(state, prevState) {
    // 主应用自身的状态响应逻辑
    this.updateMainAppUI(state);
    
    // 记录状态变化日志
    this.logStateChange('main-app', state, prevState);
  }

  // 设置子应用特定状态
  setSubAppState(subAppName, state) {
    const subApp = this.subApps.get(subAppName);
    if (subApp) {
      subApp.state = { ...subApp.state, ...state };
      
      // 可以在这里实现子应用状态与全局状态的某种映射
      this.maybeUpdateGlobalStateFromSubApp(subAppName, state);
    }
  }

  // 可能根据子应用状态更新全局状态
  maybeUpdateGlobalStateFromSubApp(subAppName, state) {
    // 例如:当子应用的用户信息变化时,同步到全局状态
    if (state.user) {
      this.actions.setGlobalState({
        user: state.user,
        lastUpdatedBy: subAppName
      });
    }
  }

  // 更新主应用UI
  updateMainAppUI(state) {
    // 实现主应用界面更新逻辑
    if (state.user) {
      this.updateUserInfo(state.user);
    }
    
    if (state.theme) {
      this.applyTheme(state.theme);
    }
  }

  // 记录状态变化
  logStateChange(source, state, prevState) {
    if (process.env.NODE_ENV === 'development') {
      console.group(`[qiankun] State changed from ${source}`);
      console.log('Previous:', prevState);
      console.log('Current:', state);
      console.groupEnd();
    }
  }
}

// 主应用中使用
export const stateBridge = new MainAppStateBridge();

// 初始化全局状态
export const initAppGlobalState = (initialState) => {
  return stateBridge.init(initialState);
};

// 为子应用提供状态桥接
export const getSubAppStateBridge = (subAppName) => {
  return stateBridge.createSubAppStateBridge(subAppName);
};
子应用状态适配器
// subapp/src/utils/global-state-adapter.js
class GlobalStateAdapter {
  constructor(props) {
    this.props = props;
    this.state = {};
    this.unsubscribe = null;
    this.listeners = new Map();
  }

  // 初始化适配器
  init() {
    if (!this.props || !this.props.onGlobalStateChange) {
      console.warn('[qiankun] Global state not available in sub-app');
      return false;
    }

    // 监听全局状态变化
    this.unsubscribe = this.props.onGlobalStateChange((state, prevState) => {
      this.handleGlobalStateChange(state, prevState);
    }, true); // 立即执行一次获取初始状态

    return true;
  }

  // 处理全局状态变化
  handleGlobalStateChange(state, prevState) {
    const prevLocalState = { ...this.state };
    this.state = state;

    // 通知所有本地监听器
    this.notifyLocalListeners(state, prevState);

    // 执行子应用特定的状态处理
    this.handleSubAppSpecificChanges(state, prevState);

    // 更新子应用UI
    this.updateSubAppUI(state, prevState);
  }

  // 设置全局状态(代理方法)
  setGlobalState(state) {
    if (this.props && this.props.setGlobalState) {
      return this.props.setGlobalState(state);
    }
    return false;
  }

  // 获取当前状态
  getGlobalState() {
    return this.props ? this.props.getGlobalState() : this.state;
  }

  // 注册本地监听器(子应用内部使用)
  onStateChange(callback, immediately = false) {
    const listenerId = Symbol('local-state-listener');
    this.listeners.set(listenerId, callback);

    if (immediately) {
      try {
        callback(this.state, this.state);
      } catch (error) {
        console.error('Local state listener error:', error);
      }
    }

    return () => {
      this.listeners.delete(listenerId);
    };
  }

  // 通知本地监听器
  notifyLocalListeners(state, prevState) {
    this.listeners.forEach((listener, id) => {
      try {
        setTimeout(() => {
          if (this.listeners.has(id)) {
            listener(state, prevState);
          }
        }, 0);
      } catch (error) {
        console.error(`Local listener ${id.toString()} error:`, error);
      }
    });
  }

  // 处理子应用特定的状态变化
  handleSubAppSpecificChanges(state, prevState) {
    // 用户信息变化
    if (state.user !== prevState.user) {
      this.handleUserChange(state.user, prevState.user);
    }

    // 主题变化
    if (state.theme !== prevState.theme) {
      this.handleThemeChange(state.theme);
    }

    // 权限变化
    if (state.user?.permissions !== prevState.user?.permissions) {
      this.handlePermissionChange(state.user?.permissions);
    }
  }

  // 更新子应用UI
  updateSubAppUI(state, prevState) {
    // 实现子应用界面更新逻辑
    // 例如:更新用户信息显示、应用主题等
  }

  // 具体的状态处理函数
  handleUserChange(user, prevUser) {
    console.log('User changed:', { from: prevUser, to: user });
    // 更新用户相关的界面和状态
  }

  handleThemeChange(theme) {
    document.documentElement.setAttribute('data-theme', theme);
  }

  handlePermissionChange(permissions) {
    // 根据新权限更新界面和功能
  }

  // 销毁适配器
  destroy() {
    if (this.unsubscribe) {
      this.unsubscribe();
    }
    this.listeners.clear();
  }
}

// 在子应用中使用
export const createGlobalStateAdapter = (props) => {
  const adapter = new GlobalStateAdapter(props);
  if (adapter.init()) {
    return adapter;
  }
  return null;
};

实际通信流程示例

状态变更传播流程
// 状态变更传播示意图
/**
 * 
 * 主应用 setGlobalState({user: newUser})
 *       ↓
 * GlobalStateManager.notifyListeners()
 *       ↓
 * 主应用监听器 ───→ 子应用A监听器 ───→ 子应用B监听器
 *       ↓               ↓               ↓
 * 更新主应用UI       更新子应用AUI     更新子应用BUI
 * 
 */
具体通信示例
// 通信过程跟踪
class CommunicationTracker {
  constructor() {
    this.messageId = 0;
    this.communicationLog = [];
  }

  trackStateChange(source, target, state, action) {
    const logEntry = {
      id: ++this.messageId,
      timestamp: Date.now(),
      source,
      target,
      state: this.sanitizeState(state),
      action,
      duration: null
    };

    this.communicationLog.push(logEntry);
    
    if (process.env.NODE_ENV === 'development') {
      console.log(`[qiankun-comm] ${source} -> ${target}:`, action, state);
    }

    return logEntry.id;
  }

  markCompletion(messageId, success = true) {
    const entry = this.communicationLog.find(log => log.id === messageId);
    if (entry) {
      entry.duration = Date.now() - entry.timestamp;
      entry.success = success;
    }
  }

  sanitizeState(state) {
    // 移除敏感信息
    const sanitized = { ...state };
    if (sanitized.user) {
      sanitized.user = { ...sanitized.user };
      delete sanitized.user.password;
      delete sanitized.user.token;
    }
    return sanitized;
  }

  getCommunicationStats() {
    const successful = this.communicationLog.filter(log => log.success);
    const failed = this.communicationLog.filter(log => log.success === false);
    
    return {
      total: this.communicationLog.length,
      successful: successful.length,
      failed: failed.length,
      averageDuration: successful.reduce((sum, log) => sum + log.duration, 0) / successful.length,
      recentMessages: this.communicationLog.slice(-10)
    };
  }
}

// 在全局状态管理器中集成跟踪
class TrackedGlobalState extends GlobalState {
  constructor() {
    super();
    this.tracker = new CommunicationTracker();
  }

  setGlobalState(state, overwrite = false) {
    const messageId = this.tracker.trackStateChange(
      'main-app', 
      'all', 
      state, 
      'setGlobalState'
    );

    try {
      const result = super.setGlobalState(state, overwrite);
      this.tracker.markCompletion(messageId, result);
      return result;
    } catch (error) {
      this.tracker.markCompletion(messageId, false);
      throw error;
    }
  }
}

关键特性总结

核心原理

发布-订阅模式:基于事件的通知机制

中心化状态存储:单一数据源

状态隔离:主应用和子应用的状态操作隔离

异步通知:使用微任务避免阻塞

通信机制

状态变更传播:主应用 → 所有监听器(包括子应用)

双向通信:子应用也可以更新全局状态

状态合并:智能合并而不是完全覆盖

错误隔离:单个监听器错误不影响其他监听器

性能优化

懒执行:使用 setTimeout 和 Promise 避免阻塞

深度克隆:确保状态不可变性

内存管理:提供清理和销毁方法

条件监听:支持立即执行和延迟执行

通过这种设计,Qiankun 实现了高效、可靠的主应用与子应用之间的状态通信,同时保持了良好的性能和可维护性。

本站提供的所有下载资源均来自互联网,仅提供学习交流使用,版权归原作者所有。如需商业使用,请联系原作者获得授权。 如您发现有涉嫌侵权的内容,请联系我们 邮箱:[email protected]