utils/qiankun.js
import { addGlobalUncaughtErrorHandler, loadMicroApp } from 'qiankun';
export const micro_conf = [
{
name: 'assistant',
entry: hostMap('http://localhost:7106/assistant/'),
container: '#sub-container1',
activeRule: '/main/assistant',
config: {
title: '多方协管'
}
},
{
name: 'safe',
entry: hostMap('http://localhost:7206/safe/'),
container: '#sub-container2',
activeRule: '/main/safe',
config: {
title: '安全监管'
}
}
];
addGlobalUncaughtErrorHandler((event) => {
console.error(event);
const { message: msg } = event;
if (msg && msg.includes('died in status LOADING_SOURCE_CODE')) {
console.error('微应用加载失败,请检查应用是否可运行');
}
});
const lifeCycles = {
beforeLoad: [(app) => console.log('before load', app)],
beforeMount: [(app) => console.log('before mount', app)],
afterUnmount: [(app) => console.log('before unmount', app)]
};
function getProps() {
return {
initialState: {}
};
}
const microList = new Map([]);
let current;
export async function loadMicroAppOnce(to) {
console.log('>>>to', to);
const conf = micro_conf.find(
(item) => ('/main' + to.path).indexOf(item.activeRule) !== -1
);
if (!conf) return;
if (current && current.activeRule === conf.activeRule) {
console.log('>>>未切换应用', current);
return;
}
const cacheMicro = microList.get(conf.activeRule);
if (cacheMicro) {
console.log('>>>已缓存应用', cacheMicro);
return;
}
const micro = loadMicroApp(
{
...conf,
props: getProps(),
lifeCycles
},
{
sandbox: true,
singular: false,
getPublicPath: (entry) => {
console.log('>>>injectPublicPath', entry);
return entry;
}
}
);
await micro.loadPromise;
console.log('>>>加载应用', micro, micro.getStatus());
if (micro.getStatus() === 'BOOTSTRAPPING') {
microList.set(conf.activeRule, micro);
current = conf;
} else {
console.log('>>>加载失败,将卸载应用以待下次重试', micro.getStatus());
current = null;
microList.delete(conf.activeRule);
typeof micro.unmount === 'function' && micro.unmount();
}
}
subContainer.vue
<template>
<div class="sub-container-wrap">
<div
v-for="micro in micro_conf"
:key="micro.name"
:id="micro.container.replace('#', '')"
v-show="
$route.path &&
('/main' + $route.path).indexOf(micro.activeRule) !== -1
"
class="sub-container-box"
></div>
</div>
</template>
<script setup>
import { loadMicroAppOnce, micro_conf } from '@/utils/qiankun';
const route = useRoute();
watch(
() => route.path,
() => loadMicroAppOnce(route),
{ immediate: true }
);
</script>
<style lang="scss" scope>
.sub-container-wrap {
width: 100%;
height: 100%;
box-sizing: border-box;
display: inline-block;
}
.sub-container-box {
height: 100%;
> div {
height: 100%;
}
}
</style>