数据通信
在微前端架构中,我们应该按业务划分出对应的子应用,而不是通过功能模块划分子应用。这么做的原因有两个:
在微前端架构中,子应用并不是一个模块,而是一个独立的应用,我们将子应用按业务划分可以拥有更好的可维护性和解耦性。
子应用应该具备独立运行的能力,应用间频繁的通信会增加应用的复杂度和耦合度。
综上所述,我们应该从业务的角度出发划分各个子应用,尽可能减少应用间的通信,从而简化整个应用,使得我们的微前端架构可以更加灵活可控。
qiankun props 传值
在注册应用信息的方法registerMicroApps中,通过props给子应用传递数据。此方法优势是用法很简单,且可以传递组件和方法,缺点是只能从主应用传递给子应用。有不少场景不太适用。
props - object - 可选,主应用需要传递给微应用的数据。
一般可通过主应用的store传递给子应用
子组件获取到的数据
initGlobalState
qiankun通过initGlobalState, onGlobalStateChange, setGlobalState实现主应用的全局状态管理
onGlobalStateChange: (callback: OnGlobalStateChangeCallback, fireImmediately?: boolean) => void, 在当前应用监听全局状态,有变更触发 callback,fireImmediately = true 立即触发 callback
setGlobalState: (state: Record<string, any>) => boolean, 按一级属性设置全局状态,微应用中只能修改已存在的一级属性
offGlobalStateChange: () => boolean,移除当前应用的状态监听,微应用 umount 时会默认调用
主应用给子应用传值
主应用 main.js
import {
initGlobalState,
} from 'qiankun';
export const initialState = {
globalLocation: {
id: 1234,
station: '北京'
}
}
const actions = initGlobalState(initialState) //初始化全局数据
actions.onGlobalStateChange((newState, prev) => {
//监听全局状态
console.log(newState, prev)
for (let key in newState) {
initialState[key] = newState[key]
}
});
子应用 action,js
// /src/qiankun/action.js
function emptyAction() {
// 提示当前使用的是空 Action
console.warn("Current execute action is empty!");
}
class Actions {
// 默认值为空 Action
actions = {
onGlobalStateChange: emptyAction,
setGlobalState: emptyAction,
};
/**
* 设置 actions
*/
setActions(actions) {
this.actions = actions;
}
/**
* 映射
*/
onGlobalStateChange() {
return this.actions.onGlobalStateChange(...arguments);
}
/**
* 映射
*/
setGlobalState() {
return this.actions.setGlobalState(...arguments);
}
}
const actions = new Actions();
export default actions;
子应用 main.js
/**
* 应用每次进入都会调用 mount 方法,通常我们在这里触发应用的渲染方法
*/
export async function mount(props) {
console.log('[vue] props from main framework', props);
props.onGlobalStateChange((state, prev) => {
// state: 变更后的状态; prev 变更前的状态
console.log('这是主应用传来的值',state, prev);
},true);//第二个参数为 true,表示立即执行一次观察者函数
actions.setActions(props) //子项目的入口文件中设置子应用的全局state
render(props)
}
子应用传值给主应用
import action from "../action";
export default {
name: "HelloWorld",
props: {
msg: String,
},
created(){
console.log('VVVVVVVVVVVVVVVVV');
},
mounted() {
// 接收state
action.onGlobalStateChange((state) => {
console.log(state);
}, true);
},
methods: {
changeValue() {
// 修改state
action.setGlobalState({
count: 789});//每次执行时都会出发一次mounted
},
},
};