主应用配置
安装依赖包
$ yarn add qiankun
注册微应用
const {publicPath, devPath} = require("../../web.config");
const getActiveRule = (activeRule) => (location) => location.pathname.startsWith(`${publicPath}${activeRule}`);
export default [
{
name: 'vueApp',
entry: `${devPath}:3000`,
container: '#microAppContainer',
activeRule: getActiveRule('/s-app'),
routerPath: '/s-app'
},
]
<template>
<div id="microAppContainer" class="single-spa-vue"></div>
</template>
import {initGlobalState, registerMicroApps, runAfterFirstMounted, start} from "qiankun";
import microAppConfig from "@/config/microAppConfig";
mounted() {
registerMicroApps(microAppConfig, {
beforeLoad: [
app => {
console.log('[LifeCycle] before load %c%s', 'color: green;', app.name);
},
],
beforeMount: [
app => {
console.log('[LifeCycle] before mount %c%s', 'color: green;', app.name);
},
],
afterUnmount: [
app => {
console.log('[LifeCycle] after unmount %c%s', 'color: green;', app.name);
},
],
},);
const {onGlobalStateChange, setGlobalState} = initGlobalState({
user: 'qiankun',
});
onGlobalStateChange((value, prev) => console.log('[onGlobalStateChange - master]:', value, prev));
setGlobalState({
ignore: 'master',
user: {
name: 'master',
},
});
start();
runAfterFirstMounted(() => {
console.log('[MainApp] first app mounted');
});
}
修改路由切换点击事件
onMenuClick(e) {
let toPath = this.pathObject[e.key];
const {path} = this.$route;
if (path !== toPath) {
history.pushState(null, null, toPath);
}
},
注册微应用路由配置
import VueView from "@/layout/VueView";
import microAppConfig from "@/config/microAppConfig";
const spaRouters = microAppConfig.map(v => {
return {
path: v.routerPath,
component: VueView,
meta: {requireLogin: true}
}
})
export default spaRouters;
Vue 微应用
- 在
src
目录新增 public-path.js
:
if (window.__POWERED_BY_QIANKUN__) {
__webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;
}
- 入口文件
main.js
修改,为了避免根 id #app
与其他的 DOM 冲突,需要限制查找范围。
import './public-path';
import {createApp} from 'vue';
import {createRouter, createWebHashHistory,} from 'vue-router';
import App from './App.vue';
import routes from './router';
import store from './store';
let router = null;
let instance = null;
let history = null;
function render(props = {}) {
const {container} = props;
history = createWebHashHistory();
router = createRouter({
history,
routes,
});
instance = createApp(App);
instance.use(router);
instance.use(store);
instance.mount(container ? container.querySelector('#app') : '#app');
}
if (!window.__POWERED_BY_QIANKUN__) {
render();
}
export async function bootstrap() {
console.log('%c ', 'color: green;', 'vue3.0 app bootstraped');
}
function storeTest(props) {
props.onGlobalStateChange &&
props.onGlobalStateChange(
(value, prev) => console.log(`[onGlobalStateChange - ${props.name}]:`, value, prev),
true,
);
props.setGlobalState &&
props.setGlobalState({
ignore: props.name,
user: {
name: props.name,
},
});
}
export async function mount(props) {
storeTest(props);
render(props);
instance.config.globalProperties.$onGlobalStateChange = props.onGlobalStateChange;
instance.config.globalProperties.$setGlobalState = props.setGlobalState;
}
export async function unmount() {
instance.unmount();
instance._container.innerHTML = '';
instance = null;
router = null;
history.destroy();
}
- 打包配置修改(
vue.config.js
):
const { name } = require('./package');
module.exports = {
devServer: {
headers: {
'Access-Control-Allow-Origin': '*',
},
},
configureWebpack: {
output: {
library: `${name}-[name]`,
libraryTarget: 'window',
jsonpFunction: `webpackJsonp_${name}`,
},
},
};