qiankun 主微应用传值详解
在微前端架构中,主应用与微应用之间的通信是至关重要的。qiankun 提供了多种方式来实现数据传递,本文将详细介绍这两种主要的传值方式:props 和 global state,并提供最佳实践和代码示例。
1. Props 传值
定义
通过在微应用的配置中使用 props 属性,主应用可以将数据传递给微应用。
特点
- 单向传递:主应用可以将数据传递给微应用,但微应用无法直接修改主应用的数据。
- 静态值:传递的值在微应用加载时确定,之后不会自动更新。
代码示例
typescript
// src/utils/qiankun/microAppsConfig.ts
import eventBus from '../../common/MeshEditorJumper/eventBus.js';
interface QaSystemProps {
eventBus: any;
initQuery?: string;
modelType?: string;
}
interface MicroAppConfig {
name: string;
entry: string;
container: string;
activeRule: string;
sandbox: boolean | {
experimentalStyleIsolation?: boolean;
strictStyleIsolation?: boolean;
};
props?: QaSystemProps;
}
const microAppsConfig: MicroAppConfig[] = [
{
name: 'qaSystem',
entry: window._env_.REACT_APP_SERVICE_QA_ENTRY,
container: '#qaSystem-root',
activeRule: '/qaSystem',
sandbox: {
experimentalStyleIsolation: true,
strictStyleIsolation: false,
},
props: {
eventBus: eventBus,
initQuery: new Date().getTime() + '',
modelType: '',
}
},
];
export { microAppsConfig };优缺点
- 优点:
- 简单易用,适合传递一些初始化数据。
- 适合不需要频繁更新的数据。
- 缺点:
- 数据是静态的,无法响应主应用的状态变化。
2. Global State 传值
定义
通过 qiankun 提供的 initGlobalState 方法,可以创建一个全局状态管理,主应用和微应用都可以访问和修改这个状态。
特点
- 双向传递:主应用和微应用都可以读取和修改全局状态。
- 动态变化:全局状态可以在运行时动态更新,微应用可以响应这些变化。
代码示例
typescript
// src/utils/qiankun/action.ts
import { initGlobalState } from 'qiankun';
const initialState = {
logInfo: {},
subscriptionsInfo: {},
};
const actions = initGlobalState(initialState);
export default actions;在微应用中使用全局状态:
typescript
// src/omnicraft/index.tsx
import { useEffect } from "react";
import action from "../utils/qiankun/action";
const MicroNode = ({
handleCardClick,
logInfo,
subscriptionsInfo,
handleOpenSub,
handleOpenPre,
handleOpenLogin,
handleOpenFeedback,
}) => {
useEffect(() => {
action.setGlobalState({
handleCardClick: (uuid: number) => handleCardClick(uuid),
logInfo: logInfo,
subscriptionsInfo: subscriptionsInfo,
handleOpenSub: (value: boolean) => handleOpenSub(value),
handleOpenPre: (value: boolean) => handleOpenPre(value),
handleOpenLogin: (value: boolean) => handleOpenLogin(value),
handleOpenFeedback: (value: boolean) => handleOpenFeedback(value),
});
}, [handleCardClick, logInfo, subscriptionsInfo, handleOpenLogin, handleOpenSub, handleOpenPre, handleOpenFeedback]);
return (
<div id="ominicraft-root"></div>
);
};
export default MicroNode;优缺点
- 优点:
- 支持双向数据绑定,主应用和微应用可以实时同步状态。
- 适合需要频繁更新和交互的数据。
- 缺点:
- 复杂性增加,可能导致状态管理混乱。
3. props + eventBus
1. 初始化config
ts
import eventBus from '../../common/MeshEditorJumper/eventBus.js';
interface QaSystemProps {
eventBus: any;
initQuery?: string;
modelType?: string;
}
interface MicroAppConfig {
name: string;
entry: string;
container: string;
activeRule: string;
sandbox: boolean | {
experimentalStyleIsolation?: boolean;
strictStyleIsolation?: boolean;
};
props?: QaSystemProps;
}
const microAppsConfig: MicroAppConfig[] = [
{
name: 'qaSystem',
entry: window._env_.REACT_APP_SERVICE_QA_ENTRY,
container: '#qaSystem-root',
activeRule: '/qaSystem',
sandbox: {
experimentalStyleIsolation: true,
strictStyleIsolation: false,
},
props: {
eventBus: eventBus,
}
},
];
const MicroAppStart = function (){
registerMicroApps(microAppsConfig);
start({
prefetch: "all",
sandbox: false
});
}
MicroAppStart();2.构建一个eventBus
ts
class EventBus {
constructor() {
this.events = {};
this.stickyEvents = {};
}
on(eventName, callback, executeSticky = true) {
if (!this.events[eventName]) {
this.events[eventName] = [];
}
this.events[eventName].push(callback);
// 如果有粘性事件,并且 executeSticky 为 true,立即执行
if (executeSticky && this.stickyEvents[eventName]) {
callback(this.stickyEvents[eventName]);
}
}
emit(eventName, data, sticky = true) {
// 如果 sticky 为 true,保存最新的事件数据
if (sticky) {
this.stickyEvents[eventName] = data;
}
const event = this.events[eventName];
if (event) {
event.forEach(callback => callback(data));
}
}
// 清除特定事件的所有监听器
off(eventName) {
delete this.events[eventName];
}
// 清除特定事件的粘性数据
clearSticky(eventName) {
delete this.stickyEvents[eventName];
}
// 获取特定事件的粘性数据
getStickyEvent(eventName) {
return this.stickyEvents[eventName];
}
}
export default new EventBus();3.主微应用更新eventBus实现传参和接收
ts
eventBus.emit('qaSystemInitData', {
initQuery: inputRef.current.value,
modelType: selectedTopic.id
});
eventBus.on('qaSystemQuery', (data: { query: string; type: string }) => {
if (data.query && data.type) {
localStorage.setItem('qaSystem:initQuery', data.query);
localStorage.setItem('qaSystem:modelType', data.type);
}
});
eventBus.off('qaSystemQuery');总结
在选择传值方式时,可以根据具体的需求来决定:
- 如果只需要传递一些初始化的静态数据,可以使用
props传值。 - 如果需要实现动态交互和状态同步,建议使用
global state传值或者eventBus。
这两种方式可以结合使用,主应用可以通过 props 传递一些初始值,同时使用 global state 进行动态数据的管理。这样可以充分利用两者的优点,构建一个灵活且高效的微前端架构。