一、qiankun版本
v2.7.2
二、主应用(基座)
若依vue2版本
三、子应用
一个只有两个页面的人脸识别项目
四、主应用改造
1.主应用安装qiankun框架
npm i qiankun -S
2.main.js中引入qiankun的注册应用函数,对子应用进行注册
import { registerMicroApps } from 'qiankun';
registerMicroApps([{
name: 'face-recognition', // 子应用名称,与子应用package.json中的name一致
entry: 'http://localhost:8080', //入口地址
container: '#qiankunContainer', //父应用提供的渲染子应用的容器
// activeRule: '/portal' //指定激活访问子应用的路由,下面的写法也可以
activeRule: location => location.pathname.startsWith('/portal')
}]);
五、子应用改造
1.子应用无需下载qiankun
2.子应用main.js暴露生命周期供主应用加载时调用
let instance = null;
function render() {
// 挂载应用
instance = new Vue({
router,
render: h => h(App)
}).$mount('#sub');//*注意:这有个坑,子应用挂载的节点不要与基座里的重复,自己单独起个id
}
// 独立运行时
//使用window.__POWERED_BY_QIANKUN__变量判断子应用是独立运行还是在基座运行
if (!window.__POWERED_BY_QIANKUN__) {
render();
}
/**
* bootstrap 只会在微应用初始化的时候调用一次,下次微应用重新进入时会直接调用 mount 钩子,不会再重复触发 bootstrap。
* 通常我们可以在这里做一些全局变量的初始化,比如不会在 unmount 阶段被销毁的应用级别的缓存等。
*/
export async function bootstrap() {
console.log('微应用初始化');
}
/**
* 应用每次进入都会调用 mount 方法,通常我们在这里触发应用的渲染方法
*/
export async function mount(props) {
console.log('微应用mount');
render();
}
/**
* 应用每次 切出/卸载 会调用的方法,通常在这里我们会卸载微应用的应用实例
*/
export async function unmount(props) {
console.log('微应用unmount');
instance.$destroy();
}
3.子应用显示在基座时字体图标不显示,及打包配置修改
// vue.config.js
chainWebpack: (config) => {
config.module
.rule('fonts')
.test(/.(ttf|otf|eot|woff|woff2)$/)
.use('url-loader')
.loader('url-loader')
.tap(options => {
options = {
// limit: 10000,
name: '/static/fonts/[name].[ext]'
};
return options;
})
.end();
},
configureWebpack: {
output: {
library: `face-recognition`,
libraryTarget: 'umd',
jsonpFunction: `webpackJsonp_${packageName}`
}
}
4. 子应用图片在基座不显示
//根目录创建 public-path.js
if (window.__POWERED_BY_QIANKUN__) {
// eslint-disable-next-line no-undef
__webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;
}
//在main.js中引入
import './public-path';
*六、主应用的额外改造
由于想实现如上图效果,在主应用点击左侧菜单,右侧部分渲染子应用对应的页面,所以需要如下改造
1.修改子应用路由
export const constantRoutes = [
{
path: '',
component: container,
name: 'container',
redirect: '/faceRecog',
children: [
{
path: '/faceRecog',
name: 'faceRecog',
component: faceRecog
},
{
path: '/faceAlarm',
name: 'faceAlarm',
component: faceAlarm
}
]
}
];
export default new Router({
mode: 'history', // 设置为history模式
base: '/portal', // base设置为portal 也就是访问 http://xx.xx.xx.xx/portal相当与访问ttp://xx.xx.xx.xx/
routes: constantRoutes
});
2.根据子应用的路由,配置主应用的菜单
3.主应用创建一个portal组件用于提供渲染子应用的容器
<template>
<div>
//对应registerMicroApps函数中的container
<div id="qiankunContainer" />
</div>
</template>
<script>
import { start } from 'qiankun';
export default {
mounted() {
if (!window.qiankunStarted) {
window.qiankunStarted = true;
start();
}
}
};
</script>
4.主应用在构建路由tree的时候,对子应用的路由单独处理,以若依的permission.js为例
遇到以portal开头的路由,即子应用的路由,直接走portal组件
5.此时点击了菜单,进入portal组件,组件的mounted内调用了qiankun的start函数,将子应用渲染到id为'qiankunContainer'的dom内
七、遇到的一些坑
1.由于若依给router-view加了key,使得组件都不会复用,所以对key增加判断,是portal组件复用,避免子应用渲染异常
2.子应用也有左侧菜单,当在基座内渲染时,怎样隐藏掉左侧菜单
使用window.__POWERED_BY_QIANKUN__变量判断是否在基座运行,对菜单显示隐藏即可