場景描述:子應用需要在接口調用和頁面渲染時,需要用到主應用登錄之后拿到的用戶數據
邏輯前提:
1、主應用在 main.js中通過 registerMicroApps注冊了子應用
2、主應用登錄之后將用戶數據傳遞給子應用
>> 原先的做法(有問題)
【具體參考 qiankun #initGlobalState】這個數據傳遞的方法是沒有問題的,只是不滿足當前的場景
1、主應用在注冊子應用時,在子應用的生命周期鉤子afterMount方法中通過setGlobalState方法將用戶數據傳遞出去
// main.js
registerMicroApps([{name: 'custproApp',entry: '/MicroCustpro/',container: '#appContainer',activeRule: 'app-custpro',},],{afterMount: [(app) => {// eslint-disable-next-lineconsole.log(`[base-app]: catch [${app.name}] afterMount`)qiankunActions.setGlobalState({userInfo: store.getters.userInfo})}],}
)
2、子應用在導出的生命周期鉤子mount方法中通過onGlobalStateChange方法監聽主應用的數據傳遞,從而拿到用戶數據
// main.js
export async function mount (props) {console.log('[app-cust] vue app mounted, props from main framework', props)render(props)// 主應用通信props.onGlobalStateChange((state) => {const { userInfo = {} } = state// 用戶信息保存if (userInfo) store.dispatch('initUserInfo', { ...userInfo })console.log('[app-cust]: catch [base-app] state')})
}
【問題現象】:主應用登錄之后加載子應用,子應用加載之后最初調用的幾個接口中并沒有帶上用戶數據,頁面渲染出來更早一點的部分也出現沒有拿到用戶數據的情況
【原因分析】:主應用在子應用 afterMount 加載完之后才傳遞的數據,子應用 mount 加載之后最初調用的接口,以及靠前一點的部分頁面渲染,可能比子應用監測到主應用傳遞的數據更早發生
>> 修改后的做法
1、主應用在注冊子應用時,在props中通過函數的方式返回主應用存儲在全局狀態 (vuex等)中的用戶數據
// main.js
registerMicroApps([{name: 'custproApp',entry: '/MicroCustpro/',container: '#appContainer',activeRule: 'app-custpro',props: getUserInfo () => ({ userInfo: store.getters.userInfo })},]
)
2、子應用在導出的生命周期鉤子mount方法中通過props從主應用的全局狀態中取到用戶數據
// main.js
export async function mount (props) {console.log('[app-cust] vue app mounted, props from main framework', props)if (props.getUserInfo) {// 用戶信息保存const { userInfo } = props.getUserInfo()if (userInfo) store.dispatch('initUserInfo', { ...userInfo })console.log('---user---', userInfo.userName, userInfo.userId)}render(props)
}