基础使用请参考qiankun官网https://qiankun.umijs.org/zh
进阶使用会遇到如下问题
- 主应用和子应用都有router,如何匹配
- 主应用如何切换子应用中的路由
- 主应用和子应用同源如何配置
主应用和子应用都有router,如何匹配
注册子应用
registerMicroApps([
{
name: 'child1', // app name registered
entry: '//localhost:7001/',
container: '#childApp',
activeRule: '/main/child1',
},
{
name: 'child2',
entry: '//localhost:7002/',
container: '#childApp',
activeRule: '/main/child2',
},
]);
主应用中路由配置,所有子应用对应的组件建议是空组件EmptyPage,因为同时会加载子应用和主应用的组件
{
path: '/main',
name: 'Layout',
component: () => import('../views/Layout.vue'),
children:[
{
path: 'user',
name: 'user',
component: () => import('../views/UserPage.vue')
},
{
path: 'child1/:pathMatch(.*)*',
name: 'child1',
component: () => import('../views/EmptyPage.vue'),
},
{
path: 'child2/:pathMatch(.*)*',
name: 'child2',
component: () => import('../views/EmptyPage.vue'),
},
}
其中layout.vue代码就是搭建一个框架,其中的router-view是为了在主应用中切换子应用,childApp的div是为了挂载渲染子应用
/** Layout.vue **/
<template>
<div>This is Dashboard On Main App</div>
<Narbar/>
<router-view></router-view>
<div id="childApp"></div>
</template
子应用的路由配置
webHistory = createWebHistory('/main/child1')
主应用如何切换子应用中的路由
在主应用中切换各个子应用就是普通的路由切换
router.push(’/main/child1’)
router.push(’/main/child2’)
在主应用中切换子应用内部的子路由,发送消息给子应用,让子应用自行切换,参考qiankun官方应用通信样例https://qiankun.umijs.org/zh/api#initglobalstatestate
主应用:
import { initGlobalState, MicroAppStateActions } from 'qiankun';
const state = {path:{child1:'/about'}}
// 初始化 state
const actions: MicroAppStateActions = initGlobalState(state);
actions.onGlobalStateChange((state, prev) => {
// state: 变更后的状态; prev 变更前的状态
console.log(state, prev);
});
actions.setGlobalState(state);
actions.offGlobalStateChange()
微应用:
// 从生命周期 mount 中获取通信方法,使用方式和 master 一致
export function mount(props) {
props.onGlobalStateChange((state, prev) => {
// state: 变更后的状态; prev 变更前的状态
console.log(state, prev);
router.push(state.path.child1)
});
props.setGlobalState(state);
}
主应用和子应用同源如何配置
简单的情况就是像上面代码一样,主应用和子应用不同源,然后直接加载,如果同源的话会复杂一些。因为域名端口全部都一样,我们能做的只有修改路径。
这时候我们会面临两个问题
- 所有应用都会多加一个后缀
- 独立子应用的路径和主应用加载自应用的路径要不一致,如果一样会出现刷新页面只加载子应用,不加载主应用的情况。
至于原理就很简单浏览器优先向服务器请求资源,这个时候还轮不到前端路由发挥,自然就加载子应用了。
针对上面两个问题我们一步一步解决
第一个问题:在所有应用后面加载publicPath,前端路由的base保持一样。
// 主应用
base = /main
publicPath = /main
//子应用
base = /single-main/single-child1
publicPath = /single-main/single-child1
第二个问题:在子应用的路由base上做文章,如果是qiankun启动就设置为和qiankun一样的base路径,不是就是用single开头的路径
webHistory = createWebHistory(window.__POWERED_BY_QIANKUN__ ? '/main/child1' : '/single-main/single-child1')
最后修改一下主应用注册的地方
registerMicroApps([
{
name: 'child1', // app name registered
entry: '/single-main/single-child1',
container: '#childApp',
activeRule: '/main/child1',
},
{
name: 'chidl2',
entry: '/single-main/single-child2',
container: '#childApp',
activeRule: '/main/child2',
},
]);
所有核心点都已列出,欢迎指正错误和不足