创建两个项目作为实现demo,一个为主应用,一个为子应用
主应用
安装 qiankun:
yarn add qiankun
或者
npm i qiankun -S
使用qiankun:
-
在 utils 内创建 微应用文件夹 microApp,同时在该文件夹内创建微应用出口文件 index.js,路由文件 microAppRouter,配置函数文件 microAppSetting。
2.路由文件 microAppRouter
// 微应用路由
const microAppRouter = [
{
name: "child", //用于应用名 容器id 应用路由基地址
url: "//localhost:10002", //应用路径(ip与端口)
props: { propsName: "主应用传递过来的数据" }, //初始化时需要传递给微应用的数据
// hidden: false,//是否启用该应用,默认false
menuName: "子应用",//自定义属性 根据需要自己配置(用在了菜单导航的名称)
},
];
export default microAppRouter;
3.配置函数文件 microAppSetting
// 引入路由
import $microAppRouter from "./microAppRouter";
// 微应用配置
const microAppSetting = {};
export default microAppSetting;
/**
* @description: 配置子应用
* @param {*}
* @return {*}
*/
microAppSetting.microApps = () => {
let apps = [];
$microAppRouter.map((item) => {
if (!item.hidden) {
apps.push({
name: item.name, //应用名(不可重复)
entry: item.url, //默认加载应用路径(ip与端口)
container: `#${item.name}`, //容器id
activeRule: `/${item.name}`, //激活该应用的路径(子应用路由基地址)
...item,
});
}
});
return apps;
};
4.微应用出口文件 index.js
// 引入 qiankun 应用注册函数 开启函数
import { registerMicroApps, start } from "qiankun";
// 引入 微应用配置文件
import $microAppSetting from "./microAppSetting";
//注册子应用
registerMicroApps($microAppSetting.microApps());
//开启
start();
5.在App.vue内配置微应用容器及跳转菜单
主应用
{{ item.menuName }}
6.在main.js文件内引入微应用出口文件 index.js
// 引入微应用文件
import "./utils/microApp/index.js";
7.运行后展示
8.在配置完子应用后的主应用展示
点击子应用菜单
子应用
1.修改子应用路由文件内路由实例属性: base 为 "/child"
const router = new VueRouter({
mode: "history",
base: "/child",
routes,
});
2.在main.js文件内导出生命周期钩子
// vue实例变量
let instance = null;
// render 函数
function render(props) {
if (props) {
console.log(props);
}
// 创建vue实例
instance = new Vue({
router,
store,
render: (h) => h(App),
}).$mount("#app");
}
// 是否使用了qiankun
if (window.__POWERED_BY_QIANKUN__) {
// 路径动态配置
__webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;
} else {
// 未使用qiankun 调用render 函数创建vue
render();
}
/**
* bootstrap 只会在微应用初始化的时候调用一次,下次微应用重新进入时会直接调用 mount 钩子,不会再重复触发 bootstrap。
* 通常我们可以在这里做一些全局变量的初始化,比如不会在 unmount 阶段被销毁的应用级别的缓存等。
*/
export async function bootstrap(props) {
console.log(props);
}
/**
* 应用每次进入都会调用 mount 方法,通常我们在这里触发应用的渲染方法
*/
export async function mount(props) {
render(props);
}
/**
* 应用每次 切出/卸载 会调用的方法,通常在这里我们会卸载微应用的应用实例
*/
export async function unmount(props) {
console.log(props);
instance.$destroy();
}
/**
* 可选生命周期钩子,仅使用 loadMicroApp(手动加载微应用) 方式加载微应用时生效
*/
export async function update(props) {
console.log("update props", props);
}
3.配置Webpack、跨域与端口号
在vue.config.js内添加:
const packageName = require("./package.json").name;
module.exports = {
// 服务配置
devServer: {
port: 10002, //端口号
// 允许跨域
headers: {
"Access-Control-Allow-Origin": "*",
},
},
// webpack 配置
configureWebpack: {
output: {
library: `${packageName}-child`,
libraryTarget: "umd",
},
或
output: {
library: `${packageName}-[name]`,
libraryTarget: 'umd',
jsonpFunction: `webpackJsonp_${packageName}`,
},
},
};
4.运行后展示
5.报 ____webpack_public_path__未定义的问题
因为 ____webpack_public_path__ 不是全局的,所以 eslint 抛出错误
解决:
根据创建项目时选择的配置,在.eslintrc.js文件或package.json文件内添加全局配置
.eslintrc.js
module.exports = {
globals: {
__webpack_public_path__: "writable",
},
};
package.json
{
"eslintConfig": {
"globals": {
"__webpack_public_path__": true
}
}
}