qiankun项目搭建实战(以Vue项目为例)
vue create master-app
vue create son1-app
vue create son2-app
npm i qiankun -S
// 在main.js文件添加如下代码
import { registerMicroApps, start } from 'qiankun';
registerMicroApps([
{
name: 'son1', // // 微应用的名字,自拟最好能一眼看出这个应用的功能
entry: '//localhost:8081', // 微应用的入口地址
container: '#sonDiv', // 微应用要挂载的容器id
activeRule: '/son1', // 微应用对应的路由匹配规则
},
{
name: 'son2', // // 微应用的名字,自拟最好能一眼看出这个应用的功能
entry: '//localhost:8082', // 微应用的入口地址
container: '#sonDiv', // 微应用要挂载的容器id
activeRule: '/son2', // 微应用对应的路由匹配规则
}
]);
start();
### 注意
============需要提供子应用回显的容器,这个容器最好放到App.vue下 代码参考如下 =============================
<template>
<div id="app">
<nav>
<router-link to="/">Home</router-link> |
<router-link to="/about">About</router-link>
<router-link to="/son1">son1</router-link>
<router-link to="/son2">son2</router-link>
</nav>
<router-view/>
<!-- 子应用挂在的容器 -->
<!-- <div id="son1"></div>
<div id="son2"></div> -->
<div id="sonDiv" class="test"></div>
</div>
</template>
<style lang="less">
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
}
nav {
padding: 30px;
a {
font-weight: bold;
color: #2c3e50;
&.router-link-exact-active {
color: #42b983;
}
}
}
</style>
<style lang="less" scoped>
.test {
width: 100%;
height: 100%;
background-color: orange;
}
</style>
### // 首先需要在子应用 son1 vue.config.js 添加如下代码
const { defineConfig } = require('@vue/cli-service')
let packageName = 'son1'
module.exports = defineConfig({
devServer: {
headers: {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Credentials': 'true',
},
},
transpileDependencies: true,
configureWebpack: {
output: {
library: `${packageName}-[name]`,
libraryTarget: 'umd',
chunkLoadingGlobal: `webpackJsonp_${packageName}`,
}
}
})
### // 然后在子项目根目录下新建 public-path.js 文件(内容如下)
if (window.__POWERED_BY_QIANKUN__) {
__webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;
}
### // 最后在子应用的入口文件 main.js 添加如下代码
import '../public-path'
import VueRouter from 'vue-router';
let router = null;
let instance = null;
function render(props = {}) {
const { container } = props;
router = new VueRouter({
base: window.__POWERED_BY_QIANKUN__ ? '/son1/' : '/',
mode: 'history',
routes,
});
instance = new Vue({
router,
render: (h) => h(App),
}).$mount(container ? container.querySelector('#app') : '#app');
}
// 独立运行时
if (!window.__POWERED_BY_QIANKUN__) {
console.log('我在独立运行中~');
render();
}
export async function bootstrap() {
console.log('[vue] vue app bootstraped');
}
export async function mount(props) {
console.log('[vue] props from main framework', props);
render(props);
}
export async function unmount() {
instance.$destroy();
instance.$el.innerHTML = '';
instance = null;
router = null;
}
### 这里需要注意的是 import routes from './router' 这行代码 routes 必须返回的是个数组才可以 vuecli 默认返回的不是一个数组,需要自行修改一下,不然会报错
### 找到router文件夹下的index.js文件 修改代码如下所示
import Vue from 'vue'
import VueRouter from 'vue-router'
import HomeView from '../views/HomeView.vue'
Vue.use(VueRouter)
const routes = [
{
path: '/',
name: 'home',
component: HomeView
},
{
path: '/about',
name: 'about',
// route level code-splitting
// this generates a separate chunk (about.[hash].js) for this route
// which is lazy-loaded when the route is visited.
component: () => import(/* webpackChunkName: "about" */ '../views/AboutView.vue')
}
]
// const router = new VueRouter({
// routes
// })
export default routes
最终效果展示
QQ录屏20240316195148
qiankun运行逻辑:
- 将主应用与子应用都运行起来后,由于主应用的main.js配置了registerMicroApps这个,里面是个数组,数组中一个对象代码一个子应用, name不太重要,运行逻辑如下:当在浏览器地址栏输入主应用的对应路由地址,主应用发现与activeRule的路由匹配上之后,会将此activeRule下的entry下跑的子应用界面渲染到container容器里(此容器我们之前写在了App.vue)
- 简单点说就是
- 主应用监听发现路由地址变化 (例如地址最后输入/son1)
- 主应用从main.js 的 registerMicroApps之中寻找对应匹配的规则地址
- 将此条规则的entry(这里填写的就是子应用目前跑在的地址),渲染到 container 下的容器里