接触qiankun框架也有一段时间了,一直没什么产出,这篇文章来源于组内同学的分享ppt,对于新人来说可能觉得没头没尾,希望大家见谅。虽然以下内容已在多个项目中得以验证,但是缺少部分小细节,大体思路如此,仅供参考思路
非常重要的3个钩子:
getQianKunConfig().then((result) => {
(window as any).qiankun.registerMicroApps(result.subApps, {
// 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);
// },
// ]
})
}).catch((err) => {
console.log(err);
});
const initState = {
user: {}
};
// 状态管理
const actions = (window as any).qiankun.initGlobalState(initState);
actions.onGlobalStateChange((state, prev) => {
console.log();
})
actions.setGlobalState({
user: ''
});
(window as any).qiankun.start();
1:在根目录下增加.env文件,将项目开发阶段所对应的端口写入,例如:VUE_APP_PORT=8081
2:在src目录下新增文件public-path.js
3:修改router/index.js文件
原有的路由配置是将项目路由返回,微前端子应用模式必须返回的为路由数组。
4:修改入口文件main.js,引入publicPath文件以及export三个子应用生命周期
// import { HttpService } from './http/interceptors'
import animated from 'animate.css'
import $http from 'axios' // 给权限用,后续权限模块更改的时候换成共用的
import Echart from 'echarts'
// 引入qiankun
// 创建微应用容器
// 注册微应用 设置微应用激活条件,微应用地址等
// 启动qiankun
// import { registerMicroApps, start, initGlobalState } from 'qiankun'
import ViewUI from 'view-design'
import 'view-design/dist/styles/iview.css'
import Vue from 'vue'
import VueCookies from 'vue-cookies'
import { Component } from 'vue-property-decorator'
import App from './App.vue'
import './assets/css/common.less'
import './assets/css/default.css'
import './assets/font/iconfont.css'
import './assets/font/iconfont.js'
import customDirective from './customDirective'
import customFilter from './customFilters'
import routes from './router'
import store from './store'
import VueRouter from 'vue-router'
import { getPageComponent, getFirstPath } from '@/assets/js/utils';
import * as userApi from '@/http/api/login';
// 引入publicPath文件
import './public-path'
Vue.config.productionTip = false;
Vue.prototype.$echarts = Echart;
Vue.config.devtools = true
Vue.use(VueCookies)
Vue.use(animated)
Vue.use(customDirective)
customFilter(Vue)
Vue.prototype.$http = $http;
Vue.use(ViewUI);
let instance
// 如果非乾坤项目中。直接指定render方法即可
if (!window.__POWERED_BY_QIANKUN__) {
// eslint-disable-next-line @typescript-eslint/no-use-before-define
render({})
}
function render (props) {
console.log(props)
const container = props.container;
const router = new VueRouter({
base: window.__POWERED_BY_QIANKUN__ ? '/qianKunMarkManage' : '',
routes
})
...
instance = new Vue({
router,
store,
mounted () {
// this.$utils.init(this)
},
render: (h) => h(App)
}).$mount(container ? container.querySelector('#app') : '#app')
}
export async function bootstrap () {
console.log('[vue] vue app bootstraped')
}
export function mount (props) {
// store.dispatch('user/setBaseUrl', props.baseUrl)
// store.commit('setBaseUrl', props.baseUrl)
// props.onGlobalStateChange((state, prev) => {
// // state: 变更后的状态; prev 变更前的状态
// console.log(state, prev)
// })
// store.commit('setQiankunPros', props)
// import * as userApi from '@/http/api/login';
render(props)
}
export async function unmount () {
instance.$destroy()
instance.$el.innerHTML = ''
instance = null
}
5:修改打包配置vue.config.js,允许开发环境跨域一节将项目打包成umd格式,因为只有打包成umd格式文件,乾坤框架才能拿到export的生命周期函数
6:乾坤框架提供了一个全局的GlobalState来共享数据。主项目初始化之后,主项目以及子项目可以监听到这个数据的变化,也能提交这个数据。
因此我们可以在主应用的main.js中增加设置以及监听的代码
7:在子应用挂载的时候进行数据的监听以及将方法设置到vuex,方便全局使用。修改子应用main.js中的mount方法
8:如果项目使用了第三方组件库,以及图片404。需要在vue.config.js文件中将字体图标以及图片转换成base64格式文件
/* eslint-disable @typescript-eslint/no-unused-vars */
// eslint-disable-next-line @typescript-eslint/no-var-requires
const path = require('path');
const isProduction = process.env.VUE_APP_ENV !== 'development'
const publicPath =
process.env.NODE_ENV === 'production'
? '/'
: `http://localhost:${process.env.VUE_APP_PORT}`
const name = 'qianKunMarkManage'
// 去掉node监控阀值
require('events').EventEmitter.defaultMaxListeners = 0;
module.exports = {
publicPath: process.env.NODE_ENV === 'production' ? '/qianKunMarkManage/' : '/', // 部署应用包时基本URL,假设部署在根目录就'/',如果要部署在‘test下’就需要'/test/'
outputDir: process.env.NODE_ENV === 'production' ? 'dist' : 'dist', // 生成的构建目录
assetsDir: process.env.NODE_ENV === 'production' ? './static' : 'static', // 静态资源相对于outputDir的目录
// publicPath: process.env.NODE_ENV === 'production' ? '/' : '/', // 部署应用包时基本URL,假设部署在根目录就'/',如果要部署在‘test下’就需要'/test/'
// outputDir: process.env.NODE_ENV === 'production' ? 'dist' : 'dist', // 生成的构建目录
// assetsDir: process.env.NODE_ENV === 'production' ? 'static' : 'static', // 静态资源相对于outputDir的目录
indexPath: 'index.html', // 指定生成index.html的输出路劲。相对于outputDir
filenameHashing: true, // 文件是否加hash
// configureWebpack: config => {
// config = {
// entry: {
// app: '/src/main.ts'
// }
// }
// },
configureWebpack: {
output: {
library: 'qianKunMarkManage',
libraryTarget: 'umd',
jsonpFunction: `webpackJsonp_${name}`
}
},
lintOnSave: true, // 编译的时候lint代码
productionSourceMap: false,
chainWebpack: config => {
config.resolve.alias
.set('@', path.join(__dirname, 'src'))
.set('pages', path.join(__dirname, 'src/pages'))
.set('api', path.join(__dirname, 'src/http/api'));
config.module
.rule('fonts')
.use('url-loader')
.loader('url-loader')
.options({
fallback: {
loader: 'file-loader',
options: {
name: 'fonts/[name].[hash:8].[ext]',
publicPath
}
}
})
.end()
config.module
.rule('images')
.use('url-loader')
.loader('url-loader')
.options({
fallback: {
loader: 'file-loader',
options: {
name: 'img/[name].[hash:8].[ext]',
publicPath
}
}
})
},
css: {
loaderOptions: {
css: {
// options here will be passed to css-loader
}
// postcss: {
// // options here will be passed to postcss-loader
// // plugins: {
// // "autoprefixer": {},
// // "postcss-px2rem-exclude": {
// // "remUnit": 192,
// // "exclude": "./node_modules/element-ui"
// // }
// // },
// // eslint-disable-next-line @typescript-eslint/no-var-requires
// plugins: [require('postcss-px2rem-exclude')({
// remUnit: 144,
// exclude: /node_modules/i
// })]
// }
}
},
devServer: {
port: process.env.VUE_APP_PORT, // 在.env中VUE_APP_PORT=8081,与父应用的配置一致
headers: {
'Access-Control-Allow-Origin': '*' // 主应用获取子应用时跨域响应头
},
proxy: {
}
}
}
{
"subApps": [
{
"name":"qianKunMarkManage",
"entry":"http://localhost:8080/",
"activeRule":"#/qianKunMarkManage",
"container": "#sunIframe",
"props": {
"baseUrl":"http://localhost:8080/"
}
}
]
}
本篇内容整理的有点乱,只有我自己能看懂,建议大家结合qiankun官方文档一并阅读。