在微前端架構(gòu)中,我們應(yīng)該按業(yè)務(wù)劃分出對(duì)應(yīng)的子應(yīng)用沐祷,而不是通過(guò)功能模塊劃分子應(yīng)用鸠信。這么做的原因有兩個(gè):
- 在微前端架構(gòu)中纵寝,子應(yīng)用并不是一個(gè)模塊,而是一個(gè)獨(dú)立的應(yīng)用星立,我們將子應(yīng)用按業(yè)務(wù)劃分可以擁有更好的可維護(hù)性和解耦性爽茴。
- 子應(yīng)用應(yīng)該具備獨(dú)立運(yùn)行的能力,應(yīng)用間頻繁的通信會(huì)增加應(yīng)用的復(fù)雜度和耦合度绰垂。
綜上所述室奏,我們應(yīng)該從業(yè)務(wù)的角度出發(fā)劃分各個(gè)子應(yīng)用,盡可能減少應(yīng)用間的通信劲装,從而簡(jiǎn)化整個(gè)應(yīng)用胧沫,使得我們的微前端架構(gòu)可以更加靈活可控。
介紹兩種通信方式
- 第一種是 qiankun 官方提供的通信方式 - Actions 通信占业,適合業(yè)務(wù)劃分清晰绒怨,比較簡(jiǎn)單的微前端應(yīng)用,一般來(lái)說(shuō)使用第一種方案就可以滿足大部分的應(yīng)用場(chǎng)景需求谦疾。
- 第二種是基于 redux 實(shí)現(xiàn)的通信方式 - Shared 通信南蹂,適合需要跟蹤通信狀態(tài),子應(yīng)用具備獨(dú)立運(yùn)行能力念恍,較為復(fù)雜的微前端應(yīng)用六剥。
通信原理
qiankun 內(nèi)部提供了 initGlobalState 方法用于注冊(cè) MicroAppStateActions 實(shí)例用于通信,該實(shí)例有三個(gè)方法峰伙,分別是:
- setGlobalState:設(shè)置 globalState - 設(shè)置新的值時(shí)疗疟,內(nèi)部將執(zhí)行 淺檢查,如果檢查到 globalState 發(fā)生改變則觸發(fā)通知词爬,通知到所有的 觀察者 函數(shù)。
- onGlobalStateChange:注冊(cè) 觀察者 函數(shù) - 響應(yīng) globalState 變化权均,在 globalState 發(fā)生改變時(shí)觸發(fā)該 觀察者 函數(shù)顿膨。
-
offGlobalStateChange:取消 觀察者 函數(shù) - 該實(shí)例不再響應(yīng) globalState 變化。
我們從上圖可以看出叽赊,我們可以先注冊(cè) 觀察者 到觀察者池中恋沃,然后通過(guò)修改 globalState 可以觸發(fā)所有的 觀察者 函數(shù),從而達(dá)到組件間通信的效果必指。
主應(yīng)用的工作
首先囊咏,我們?cè)谥鲬?yīng)用中注冊(cè)一個(gè) MicroAppStateActions 實(shí)例并導(dǎo)出,代碼實(shí)現(xiàn)如下:
// micro-app-main/src/shared/actions.ts
import { initGlobalState, MicroAppStateActions } from "qiankun";
const initialState = {};
const actions: MicroAppStateActions = initGlobalState(initialState);
export default actions;
在注冊(cè) MicroAppStateActions 實(shí)例后,我們?cè)谛枰ㄐ诺慕M件中使用該實(shí)例梅割,并注冊(cè) 觀察者 函數(shù)霜第,我們這里以登錄功能為例,實(shí)現(xiàn)如下:
// micro-app-main/src/pages/login/index.vue
import actions from "@/shared/actions";
import { ApiLoginQuickly } from "@/apis";
@Component
export default class Login extends Vue {
$router!: VueRouter;
// `mounted` 是 Vue 的生命周期鉤子函數(shù)户辞,在組件掛載時(shí)執(zhí)行
mounted() {
// 注冊(cè)一個(gè)觀察者函數(shù)
actions.onGlobalStateChange((state, prevState) => {
// state: 變更后的狀態(tài); prevState: 變更前的狀態(tài)
console.log("主應(yīng)用觀察者:token 改變前的值 為 ", prevState.token);
console.log("主應(yīng)用觀察者:登錄狀態(tài)發(fā)生改變泌类,改變后的 token 的值為 ", state.token);
});
}
async login() {
// ApiLoginQuickly 是一個(gè)遠(yuǎn)程登錄函數(shù),用于獲取 token底燎,詳見(jiàn) Demo
const result = await ApiLoginQuickly();
const { token } = result.data.loginQuickly;
// 登錄成功后刃榨,設(shè)置 token
actions.setGlobalState({ token });
}
}
---------------未完-----------