老大:我们需要像微服务一样搞个微前端
我:好的,www.baidu.com/s?wd=微前端 灵魂吸收天地精华...
... 30分钟后
我:qiankun好像符合老大的需求,这是地址您看看:qiankun.umijs.org/zh
老大:好,尽快实现!
我:又要看文档和写demo了(=_=!!!)
内心:qiankun对于目前市面上不同框架的兼容性、是否可以支持小程序应用、应用之间如何通信、样式隔离怎么处理(balabala...)
怀着忐忑的内心开始了主应用(基座)的搭建
第一步 搭建主应用
vue create qiankun-main
... 10秒钟后
... npm run serve
... 哇!vue的页面好酷炫 !! 不对,我他喵是来学习怎么搭建qiankun基座的~
1.安装qiankun
cnpm i qiankun -S
2.基座 - 微应用基础信息配置
src/micro-app.js
const microApps = [{
name: 'undefined',
entry: '//localhost:8888/',
activeRule: '/undefined',
container: '#undefined',
props: {
routerBase: '/undefined',
routerList: [{
path: '/qrCode',
name: 'qrCode',
component: 'qrCode'
}],
desc: 'undefined一个神奇的前端组织'
}
}]
export default microApps;
3.基座 - 微应用服务配置
src/micro.js
import { registerMicroApps , start } from 'qiankun'
import microApps from './micro-apps'
/**
*
* @param {Array} microList 微应用列表
*/
export default function (microList) {
registerMicroApps(microList ?? microApps, {
// 生命周期 - beforeLoad(连接微应用前调用)
beforeLoad: app => {
console.log(`【undefiend组织】预连接${app.name}微应用`)
},
// 生命周期 - beforeMount(挂载前调用)
beforeMount: [
app => {
console.log(`【undefiend组织】即将挂载${app.name}微应用`)
}
],
// 生命周期 - afterMount(挂载后调用)
afterMount: [
app => {
console.log(`【undefiend组织】已经挂载${app.name}微应用`)
}
],
// 生命周期 - afterUnmount(卸载后调用)
afterUnmount: [
app => {
console.log(`【undefiend组织】已卸载了${app.name}微应用`)
}
]
});
// 启动基座服务
start({
singular: false,
sandbox: {
strictStyleIsolation: true
}
});
}
4.基座 - 入口文件配置
App.vue
<template>
<div id="app">
<h1>我是基座</h1>
<!-- undefined是microApps内container对应的id -->
<div id="undefined"></div>
</div>
</template>
<script>
import micro from './micro'
export default {
name: 'App',
created(){
// 启动微前端
micro();
}
}
</script>
基座 - 笔记
1.1.App.vue内必须有微应用基础信息配置
container: '#undefined'
<div id="undefined"></div>
1.2.路由配置推荐选择history
方便支持路由下发功能
1.3.微应用基础信息配置的props可传所有你想共享给微应用的内容
---------- 美丽的分割线 ---------
5.微应用 - 配置运行时的publicPath
(function() {
if (window.__POWERED_BY_QIANKUN__) {
if (process.env.NODE_ENV === 'development') {
// eslint-disable-next-line no-undef
__webpack_public_path__ = '//localhost:8888/'
return;
}
// eslint-disable-next-line no-undef
__webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;
}
})();
6.微应用 - webpack配置
vue.config.js
const packageName = require('./package.json').name
module.exports = {
configureWebpack: {
output: {
library: `${packageName}-[name]`,
libraryTarget: 'umd', // 把子应用打包成 umd 库格式
jsonpFunction: `webpackJsonp_${packageName}`,
},
},
devServer: {
port: 8888, // 配置本地代理
headers: {
'Access-Control-Allow-Origin': '*' // 解决跨域
}
}
}
7.微应用 - 路由基础配置
router/undefiendRouter.js
const undefiendRouter = [{
path: '/qrCode',
name: 'qrCode',
component: () => import('../views/qrCode.vue')
}]
export default undefiendRouter
8.微应用 - 路由
router/index.js
import Vue from 'vue';
import VueRouter from 'vue-router'
import undefiendRouter from './undefiendRouter'
Vue.use(VueRouter)
const routes = [...undefiendRouter]
const router = new VueRouter({
base: process.env.BASE_URL,
routes,
mode: 'history'
})
export default router
9.微应用 - 入口文件
main.js
import Vue from 'vue'
import App from './App.vue'
import VueRouter from 'vue-router'
import routers from './router'
import './public-path'
Vue.config.productionTip = false
// true:一起运行,false:独立运行
const isNotQiankun = !window.__POWERED_BY_QIANKUN__
Vue.config.productionTip = false
let instance = null
// 如果独立运行时,则会执行这里
if (isNotQiankun) render();
/**
* 微应用初始化
* @param {Object} props - 主应用传递的参数
*/
function render(props) {
const {
container,
routerBase,
routerList
} = props ?? {}
// 初始化路由
const router = routerList ? new VueRouter({
base: routerBase,
routes: routerList.map(m => {
return {
...m,
component: () => import(`@/views/${m.component}.vue`)
}
}) ?? [],
mode: 'history'
}) : routers
instance = new Vue({
router,
render: (h) => h(App)
}).$mount(container ? container.querySelector('#app') : '#app')
}
/**
* qiankun 框架子应用的三个生命周期
* bootstrap 初始化
* mount 渲染时
* unmount 卸载
*/
export async function bootstrap(props) {
console.log('---undefiend---主应用连接中---',props);
}
export async function mount(props) {
console.log('---undefiend---渲染中---',props);
render(props)
}
export async function unmount() {
console.log('---undefiend---卸载中---');
instance.$destroy()
instance.$el.innerHTML = ''
instance = null
}