上来就干货!
主应用(基座)
h5_config.js 配置(引入到index.html)
window.SITE_CONFIG = {};
window.SITE_CONFIG['appName'] = '微前端‘;
window.SITE_CONFIG['storeState'] = {} // vuex本地储存初始化状态(用于不刷新页面的情况下,也能重置初始化项目中所有状态)
//微应用
window.MicroPre = 'http://127.0.0.1'
window.microApps = [
// 子应用1
{
name: 'subApp1',
entry: MicroPre+':8001/',
container: '#micro-app',
activeRule: '/subapp1',
},
// 子应用2
{
name: 'subApp2',
entry: MicroPre+':8002/',
container: '#micro-app',
activeRule: '/subapp2',
},
]
main.js
import Vue from 'vue'
import App from './App'
import router from './router'
import store from './store'
import http from '@/utils/request'
import cloneDeep from 'lodash/cloneDeep'
//==========================微前端=====start
import { registerMicroApps, start, addGlobalUncaughtErrorHandler } from 'qiankun';
// 子应用
window.microApps = window.microApps.map(item=>{
item.props = {
microData:{
entry:item.entry,
parentStore:store,
parentRouter:router,
ProjectData: '额外参数'
}
}
return item;
})
registerMicroApps(window.microApps,{
beforeLoad: (app) => {
store.commit("qiankunFinish",true);
console.log('beforeLoad, 子应用注册:', app.name)
},
beforeMount: (app) => {
console.log('beforeMount,子应用挂载前:', app.name)
},
afterMount: (app) => {
store.commit("qiankunFinish",false);
console.log('afterMount,子应用挂载:', app.name)
},
beforeUnmount:(app)=>{
store.commit("qiankunFinish",true);
console.log('beforeUnmount,子应用卸载前:', app.name)
},
afterUnmount: (app) =>{
store.commit("qiankunFinish",false);
console.log("afterUnmount,卸载后", app.name)
},
});
addGlobalUncaughtErrorHandler(e => {
console.log('qk error:', e)
const {message: msg} =e
if(msg&&msg.includes('died in status LOADING_SOURCE_CODE')){
console.log('微应用加载失败, 请检查应用是否可用')
}
})
start({prefetch:true});
//==========================微前端=====end
Vue.config.productionTip = false
// 挂载全局
Vue.prototype.$http = http
// 保存整站vuex本地储存初始状态
window.SITE_CONFIG['storeState'] = cloneDeep(store.state)
// 主应用(基座)
new Vue({
router,
store,
render: h => h(App)
}).$mount('#micro-service')
子应用
创建public-path
if (window.__POWERED_BY_QIANKUN__) {
__webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;
}
创建qiankun.js
import './public-path'; // 微前端路径
import Vue from 'vue';
import Router from 'vue-router'
import Cookies from 'js-cookie'
import http from '@/utils/request'
Vue.config.productionTip = false
Vue.use(Router);
// 挂载全局
Vue.prototype.$http = http
/**
*
* @param {*} App
* @param {*} store
* @param {*} setting 微服务配置
* @param {*} projectFiles 文件夹下的路由
* @param {*} otherRoutes :各自项目自定义的路由
* @returns
*/
export default function qiankun(App, store, setting, projectFiles,otherRoutes=[]){
let instance = ''
let router = ''
const isQiankun = !!window.__POWERED_BY_QIANKUN__;//当前是微
function render(props={}) {
const { container } = props;
const defaultRoutes = [...otherRoutes];
router = new Router({
base: isQiankun ? `/${setting.QIANKUN_APP_NAME}` : setting[process.env.NODE_ENV],
mode: 'history',
scrollBehavior: () => ({ y: 0 }),
routes:defaultRoutes
})
Vue.config.performance = process.env.NODE_ENV === 'development';
instance = new Vue({
router,
store,
render: h => h(App)
}).$mount(container ? container.querySelector(`#${setting.QIANKUN_APP_NAME}`) : `#${setting.QIANKUN_APP_NAME}`);
}
// 微前端钩子
async function bootstrap() {
console.log('[vue] 微应用初始化时调用一次');
}
async function mount(props) {
const microData = props.microData;
window.entry = microData.entry || "";
window.ProjectData = microData.ProjectData;
window.parentStore = microData.parentStore;
window.parentRouter = microData.parentRouter;
console.log(window.parentStore)
console.log('[vue] 应用每次进入都会触发渲染', props);
let token = window.parentStore.state.token
token && Cookies.set('token', window.parentStore.state.token)
render(props);
}
async function unmount() {
console.log('[vue] 应用每次切出/卸载都会触发');
instance.$destroy();
instance.$el.innerHTML = '';
instance = null;
router = null;
window.SITE_CONFIG['dynamicMenuRoutesHasAdded'] = false;
console.log('销毁成功')
}
return {render, bootstrap, mount, unmount}
}
setting.js 配置
module.exports = {
QIANKUN_APP_NAME: "subApp1",// 子应用的名称
production: '/child/subApp1/', // 生产环境打包路径(根据实际部署环境配置)
devlopment: './', // 本地运行路径
}
main.js
import Vue from 'vue';
import App from './App'
import * as directiverData from '@/utils/directive';
import store from './store'
import qiankun from '@/qiankun'
import cloneDeep from 'lodash/cloneDeep'
for(let name in directiverData){
Vue.directive(name,{inserted:directiverData[name]});
}
const setting = require('./setting.js')
window.SITE_CONFIG['storeState'] = cloneDeep(store.state)
Vue.prototype.$setting = setting
const projectFiles = require.context('./views', true, /\.vue$/).keys()
const init = qiankun(App, store, setting, projectFiles)
// 独立运行时
if (!window.__POWERED_BY_QIANKUN__) {
console.log('独立')
init.render();
}
// 抛出乾坤钩子
export const {bootstrap,mount,unmount} = init;