qiankun 前端微应用框架,包含主应用和多个子应用。使用场景,一个项目有多个子项目组成,像我碰到,一个项目有大屏和后台管理平台
可以基于qiankun 框架,将后台管理平台写一个项目,大屏也写一个项目
基于 https://github.com/fengxianqi/qiankun-example 大佬的项目
优点
- 方便多人开发,各自管理自己的包
- 类似于iframe,有一个主应用,可以共享属性
- 可以指定启动某1个或多个项目,打包也是如此
- 子应用的框架不受限制,react,html,vue,angluar都行
组成介绍
- 主应用,又称为基座
- 子应用
关键代码介绍
-
main 主应用,由vue框架编写
在main/main.js中
安装qiankun
npm install qiankun --save
import Vue from 'vue' import App from './App.vue' import { registerMicroApps, start, setDefaultMountApp } from 'qiankun' import microApps from './micro-app' import 'nprogress/nprogress.css' Vue.config.productionTip = false const instance = new Vue({ render: h => h(App) }).$mount('#app') // 定义loader方法,loading改变时,将变量赋值给App.vue的data中的isLoading function loader (loading) { if (instance && instance.$children) { // instance.$children[0] 是App.vue,此时直接改动App.vue的isLoading instance.$children[0].isLoading = loading } } // 给子应用配置加上loader方法 const apps = microApps.map(item => { return { ...item, loader } }) // **注册子应用** registerMicroApps(apps, { beforeLoad: app => { console.log('before load app.name====>>>>>', app.name) }, beforeMount: [ app => { console.log('[LifeCycle] before mount %c%s', 'color: green;', app.name) } ], afterMount: [ app => { console.log('[LifeCycle] after mount %c%s', 'color: green;', app.name) } ], afterUnmount: [ app => { console.log('[LifeCycle] after unmount %c%s', 'color: green;', app.name) } ] }) setDefaultMountApp('/sub-vue') start()
-
每个子应用
引入public-path.js
(function () { if (window.__POWERED_BY_QIANKUN__) { if (process.env.NODE_ENV === 'development') { // eslint-disable-next-line __webpack_public_path__ = `//localhost:${process.env.VUE_APP_PORT}${process.env.BASE_URL}` return } // eslint-disable-next-line __webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__ // __webpack_public_path__ = `${process.env.BASE_URL}/` } })()
public-path.js作用:这里配置主要的作用是,当通过乾坤调用时动态的给webpack的public_path 赋予主应用的根路径。
main.js
import './public-path' import Vue from 'vue' import App from './App.vue' import routes from './router' import { store as commonStore } from 'common' import store from './store' import VueRouter from 'vue-router' Vue.config.productionTip = false let instance = null function render (props = {}) { console.log(111111) const { container, routerBase } = props const router = new VueRouter({ base: window.__POWERED_BY_QIANKUN__ ? routerBase : process.env.BASE_URL, mode: 'history', routes }) console.log('vue1---', router) instance = new Vue({ router, store, render: (h) => h(App) }).$mount(container ? container.querySelector('#app') : '#app') } if (!window.__POWERED_BY_QIANKUN__) { // 这里是子应用独立运行的环境,实现子应用的登录逻辑 // 独立运行时,也注册一个名为global的store module commonStore.globalRegister(store) // 模拟登录后,存储用户信息到global module const userInfo = { name: '我是独立运行时名字叫张三' } // 假设登录后取到的用户信息 store.commit('global/setGlobalState', { user: userInfo }) render() } export async function bootstrap () { console.log('[vue] vue app bootstraped') } export async function mount (props) { console.log('[vue] props from main framework', props) commonStore.globalRegister(store, props) render(props) } export async function unmount () { instance.$destroy() instance.$el.innerHTML = '' instance = null }
-
配置public-path.js,和main.js 同一层目录
-
引入public-path.js
3.配置render函数 -
导出乾坤会用到的生命周期函数