vue vue-cli qiankun
2main\src\micro-app.js
const microApps = [
{
name: 'vue-one',
entry: process.env.VUE_APP_VUE_ONE,
activeRule: '/vue-one'
},
{
name: 'vue-two',
entry: process.env.VUE_APP_VUE_TWO,
activeRule: '/vue-two'
}
]
const apps = microApps.map(item => {
return {
...item,
container: '#subapp-viewport', // 子应用挂载的div
props: {
routerBase: item.activeRule, // 下发基础路由
}
}
})
export default apps
3. main\src\main.js
import { createApp } from "vue";
import App from './App.vue'
import { registerMicroApps, start, setDefaultMountApp } from 'qiankun'
import microApps from './micro-app'
const app = createApp(App);
app.mount("#app");
const config = {
beforeLoad: [
app => {
console.log("%c before load",
'background:#0f0 ; padding: 1px; border-radius: 3px; color: #fff',
app);
}
], // 挂载前回调
beforeMount: [
app => {
console.log("%c before mount",
'background:#f1f ; padding: 1px; border-radius: 3px; color: #fff',
app);
}
], // 挂载后回调
afterUnmount: [
app => {
console.log("%c after unload",
'background:#a7a ; padding: 1px; border-radius: 3px; color: #fff',
app);
}
] // 卸载后回调
}
registerMicroApps(microApps, config)
setDefaultMountApp(microApps[0].activeRule) // 默认打开第一个子项目
start()
4. main\src\App.vue
<template>
<div id="app">
<div class="layout-header">
<div class="logo">QIANKUN-LIUMING</div>
<ul class="sub-apps">
<li
v-for="item in microApps"
:class="{ active: item.activeRule === current }"
:key="item.name"
@click="goto(item)"
>
{{ item.name }}
</li>
</ul>
</div>
<div id="subapp-viewport"></div>
</div>
</template>
<script>
import microApps from "./micro-app";
export default {
name: "App",
data() {
return {
microApps,
current: "/sub-vue"
};
},
methods: {
goto(item) {
console.log(item);
this.current = item.activeRule;
history.pushState(null, item.activeRule, item.activeRule); // 没引入路由,所以不能用路由切换
}
},
created() {
sessionStorage.setItem("token", "tokenInfo");
const path = window.location.pathname;
if (this.microApps.findIndex((item) => item.activeRule === path) >= 0) {
this.current = path;
}
}
};
</script>
<style>
html,
body {
margin: 0 !important;
padding: 0;
}
.layout-header {
height: 50px;
width: 100%;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
line-height: 50px;
position: relative;
}
.logo {
float: left;
margin: 0 50px;
}
.sub-apps {
list-style: none;
margin: 0;
overflow: hidden;
}
.sub-apps li {
list-style: none;
padding: 0 20px;
cursor: pointer;
float: left;
}
.sub-apps li.active {
color: #42b983;
text-decoration: underline;
}
</style>
6. main\src\components\HelloWorld.vue
<template>
<div class="hello">
<h1>{{ msg }}</h1>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
props: {
msg: String
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
h3 {
margin: 40px 0 0;
}
ul {
list-style-type: none;
padding: 0;
}
li {
display: inline-block;
margin: 0 10px;
}
a {
color: #42b983;
}
</style>
7. main\.env.development
VUE_APP_VUE_ONE=http://localhost:5501
VUE_APP_VUE_TWO=http://localhost:5502
8. main\.env.production
VUE_APP_VUE_ONE=http://localhost:5050/subapp/vue-one/
VUE_APP_VUE_TWO=http://localhost:5050/subapp/vue-two/
9. main\.gitignore
.DS_Store
node_modules
/dist
# local env files
.env.local
.env.*.local
# Log files
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
10. main\babel.config.js
module.exports = {
presets: [
'@vue/cli-plugin-babel/preset'
]
}
11. main\jsconfig.json
{
"compilerOptions": {
"target": "es5",
"module": "esnext",
"baseUrl": "./",
"moduleResolution": "node",
"paths": {
"@/*": [
"src/*"
]
},
"lib": [
"esnext",
"dom",
"dom.iterable",
"scripthost"
]
}
}
12. main\package.json
{
"name": "main",
"version": "0.1.0",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint"
},
"dependencies": {
"core-js": "^3.8.3",
"qiankun": "^2.8.4",
"vue": "^3.2.13"
},
"devDependencies": {
"@babel/core": "^7.12.16",
"@babel/eslint-parser": "^7.12.16",
"@vue/cli-plugin-babel": "~5.0.0",
"@vue/cli-plugin-eslint": "~5.0.0",
"@vue/cli-service": "~5.0.0",
"eslint": "^7.32.0",
"eslint-plugin-vue": "^8.0.3"
},
"eslintConfig": {
"root": true,
"env": {
"node": true
},
"extends": [
"plugin:vue/vue3-essential",
"eslint:recommended"
],
"parserOptions": {
"parser": "@babel/eslint-parser"
},
"rules": {}
},
"browserslist": [
"> 1%",
"last 2 versions",
"not dead",
"not ie 11"
]
}
13. main\vue.config.js
const port = 5501;//端口要和main里面配置的入口一致
const { name } = require('../package.json')
module.exports = {
publicPath: "./",
devServer: {
port,
headers: {
'Access-Control-Allow-Origin': '*'
}
},
configureWebpack: {
output: {
// 把子应用打包成 umd 库格式
library: `${name}-[name]`,
libraryTarget: 'umd',
chunkLoadingGlobal: `webpackJsonp_${name}`
}
}
二. 子项目