創(chuàng)建兩個項目作為實現(xiàn)demo榔至,一個為主應(yīng)用庸论,一個為子應(yīng)用
主應(yīng)用
安裝 qiankun:
yarn add qiankun
或者
npm i qiankun -S
使用qiankun:
-
在 utils 內(nèi)創(chuàng)建 微應(yīng)用文件夾 microApp,同時在該文件夾內(nèi)創(chuàng)建微應(yīng)用出口文件 index.js,路由文件 microAppRouter,配置函數(shù)文件 microAppSetting薇溃。
2.路由文件 microAppRouter
// 微應(yīng)用路由
const microAppRouter = [
{
name: "child", //用于應(yīng)用名 容器id 應(yīng)用路由基地址
url: "http://localhost:10002", //應(yīng)用路徑(ip與端口)
props: { propsName: "主應(yīng)用傳遞過來的數(shù)據(jù)" }, //初始化時需要傳遞給微應(yīng)用的數(shù)據(jù)
// hidden: false,//是否啟用該應(yīng)用,默認(rèn)false
menuName: "子應(yīng)用",//自定義屬性 根據(jù)需要自己配置(用在了菜單導(dǎo)航的名稱)
},
];
export default microAppRouter;
3.配置函數(shù)文件 microAppSetting
// 引入路由
import $microAppRouter from "./microAppRouter";
// 微應(yīng)用配置
const microAppSetting = {};
export default microAppSetting;
/**
* @description: 配置子應(yīng)用
* @param {*}
* @return {*}
*/
microAppSetting.microApps = () => {
let apps = [];
$microAppRouter.map((item) => {
if (!item.hidden) {
apps.push({
name: item.name, //應(yīng)用名(不可重復(fù))
entry: item.url, //默認(rèn)加載應(yīng)用路徑(ip與端口)
container: `#${item.name}`, //容器id
activeRule: `/${item.name}`, //激活該應(yīng)用的路徑(子應(yīng)用路由基地址)
...item,
});
}
});
return apps;
};
4.微應(yīng)用出口文件 index.js
// 引入 qiankun 應(yīng)用注冊函數(shù) 開啟函數(shù)
import { registerMicroApps, start } from "qiankun";
// 引入 微應(yīng)用配置文件
import $microAppSetting from "./microAppSetting";
//注冊子應(yīng)用
registerMicroApps($microAppSetting.microApps());
//開啟
start();
5.在App.vue內(nèi)配置微應(yīng)用容器及跳轉(zhuǎn)菜單
<template>
<!-- 主應(yīng)用dom id 不能與子應(yīng)用dom id 重復(fù) -->
<div id="fapp">
<el-menu
:default-active="activeIndex"
class="el-menu-demo"
mode="horizontal"
:router="true"
>
<!-- 主應(yīng)用 -->
<el-menu-item index="/">主應(yīng)用</el-menu-item>
<!-- 子應(yīng)用 -->
<el-menu-item
v-for="item in microAppDom_Router"
:key="item.name"
:index="`/${item.name}`"
>{{ item.menuName }}</el-menu-item
>
</el-menu>
<!-- 主應(yīng)用路由出口 -->
<router-view></router-view>
<!-- 微應(yīng)用dom容器 -->
<div
v-for="item in microAppDom_Router"
:key="item.name"
class="microAppBox"
:id="item.name"
></div>
</div>
</template>
<script>
// 引入子應(yīng)用路由
import $microAppRouter from "@/utils/microApp/microAppRouter";
export default {
name: "Home",
data() {
return {
// 默認(rèn)路由
activeIndex: "/",
// 微應(yīng)用容器及路由list
microAppDom_Router: $microAppRouter,
};
},
created() {},
};
</script>
6.在main.js文件內(nèi)引入微應(yīng)用出口文件 index.js
// 引入微應(yīng)用文件
import "./utils/microApp/index.js";
7.運行后展示
8.在配置完子應(yīng)用后的主應(yīng)用展示
點擊子應(yīng)用菜單
子應(yīng)用
1.修改子應(yīng)用路由文件內(nèi)路由實例屬性: base 為 "/child"
const router = new VueRouter({
mode: "history",
base: "/child",
routes,
});
2.在main.js文件內(nèi)導(dǎo)出生命周期鉤子
// vue實例變量
let instance = null;
// render 函數(shù)
function render(props) {
if (props) {
console.log(props);
}
// 創(chuàng)建vue實例
instance = new Vue({
router,
store,
render: (h) => h(App),
}).$mount("#app");
}
// 是否使用了qiankun
if (window.__POWERED_BY_QIANKUN__) {
// 路徑動態(tài)配置
__webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;
} else {
// 未使用qiankun 調(diào)用render 函數(shù)創(chuàng)建vue
render();
}
/**
* bootstrap 只會在微應(yīng)用初始化的時候調(diào)用一次汗贫,下次微應(yīng)用重新進(jìn)入時會直接調(diào)用 mount 鉤子,不會再重復(fù)觸發(fā) bootstrap秸脱。
* 通常我們可以在這里做一些全局變量的初始化落包,比如不會在 unmount 階段被銷毀的應(yīng)用級別的緩存等。
*/
export async function bootstrap(props) {
console.log(props);
}
/**
* 應(yīng)用每次進(jìn)入都會調(diào)用 mount 方法摊唇,通常我們在這里觸發(fā)應(yīng)用的渲染方法
*/
export async function mount(props) {
render(props);
}
/**
* 應(yīng)用每次 切出/卸載 會調(diào)用的方法咐蝇,通常在這里我們會卸載微應(yīng)用的應(yīng)用實例
*/
export async function unmount(props) {
console.log(props);
instance.$destroy();
}
/**
* 可選生命周期鉤子,僅使用 loadMicroApp(手動加載微應(yīng)用) 方式加載微應(yīng)用時生效
*/
export async function update(props) {
console.log("update props", props);
}
3.配置Webpack巷查、跨域與端口號
在vue.config.js內(nèi)添加:
const packageName = require("./package.json").name;
module.exports = {
// 服務(wù)配置
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 拋出錯誤
解決:
根據(jù)創(chuàng)建項目時選擇的配置,在.eslintrc.js文件或package.json文件內(nèi)添加全局配置
.eslintrc.js
module.exports = {
globals: {
__webpack_public_path__: "writable",
},
};
package.json
{
"eslintConfig": {
"globals": {
"__webpack_public_path__": true
}
}
}