背景:Qiankun 只有一个子应用,主应用控制所有动态路由(包括子应用的所有路由)
📌 分析
- 只有 一个 子应用(Vue2 )。
- 主应用(Vue3) 统一管理 所有路由(包括子应用的路由)。
- 子应用 不处理自己的路由,而是交由主应用管理。
官方文档较少
编辑
补充
- 主应用 维护完整的
routes,包括主应用自己的页面和子应用的所有路由。 - 子应用 只作为一个“页面”加载,不处理自己的路由,主应用通过
props传递路由信息。
1️⃣ 主应用 router/index.js
import { createRouter, createWebHistory } from 'vue-router';
import Home from '@/views/Home.vue';
import SubAppContainer from '@/views/SubAppContainer.vue'; // 用于挂载子应用的组件
const routes = [
{ path: '/', component: Home },
{ path: '/sub-apps/:pathMatch(.*)*', component: SubAppContainer }, // 所有子应用的路由交给 SubAppContainer 处理
];
const router = createRouter({
history: createWebHistory(),
routes
});
export default router;
2️⃣ 创建 views/SubAppContainer.vue
<template>
<div>
<h1>子应用</h1>
<div id="subAppContainer"></div>
</div>
</template>
<script>
import { watch, onMounted, onUnmounted } from 'vue';
import { loadMicroApp } from 'qiankun';
import { useRoute } from 'vue-router';
export default {
setup() {
const route = useRoute();
let microApp = null;
onMounted(() => {
microApp = loadMicroApp({
name: 'vueSubApp',
entry: '//localhost:8081',
container: '#subAppContainer',
props: {
basePath: route.fullPath // 传递当前路由给子应用
}
});
});
watch(() => route.fullPath, (newPath) => {
if (microApp && microApp.update) {
microApp.update({ basePath: newPath }); // 主应用切换路由时通知子应用
}
});
onUnmounted(() => {
if (microApp) microApp.unmount();
});
return {};
}
};
</script>
3️⃣ 子应用 main.js
import { createApp } from 'vue';
import App from './App.vue';
import router from './router';
let instance = null;
function render(props = {}) {
const { container, basePath } = props;
router.replace(basePath || '/'); // 子应用使用主应用传递的路由
instance = createApp(App);
instance.use(router);
instance.mount(container ? container.querySelector('#app') : '#app');
}
export async function bootstrap() {}
export async function mount(props) {
render(props);
}
export async function unmount() {
instance.unmount();
}
4️⃣ 子应用 router/index.js
import { createRouter, createWebHistory } from 'vue-router';
import PageA from '@/views/PageA.vue';
import PageB from '@/views/PageB.vue';
const routes = [
{ path: '/', redirect: '/pageA' },
{ path: '/pageA', component: PageA },
{ path: '/pageB', component: PageB }
];
const router = createRouter({
history: createWebHistory(), // 直接使用 history 模式,主应用控制路径
routes
});
export default router;