测试仓库:
祖应用:https://gitee.com/yu_chu_xu/qiankun_parent.git
父应用:https://gitee.com/yu_chu_xu/qiankun_main.git
子应用:https://gitee.com/yu_chu_xu/qiankun_sub.git
qiankun官网:qiankun - qiankun
祖应用配置
main.js (入口文件)
import { registerMicroApps, start, initGlobalState } from 'qiankun'
// 由于本身有window.__POWERED_BY_QIANKUN__参数,sub应用无法判断自己在第几层
// 设置一个全局参数,让sub应用检测到该参数则说明自己作为孙子应用运行
window.__POWERED_BY_QIANKUN_PARENT__ = true
// 子应用相关配置
//路由规则匹配activeRule,当匹配到该路由则会加载对应微应用到对应的container, 并依次调用微应用暴露出的生命周期钩子
const apps = [
{
name: 'qiankun-main',
entry: '//localhost:10001',
container: '#main',
activeRule: '/main'
}
]
// 注册应用
registerMicroApps(apps)
// 启动
start({
sandbox: true,
prefetch: false
})
// 给微应用传参
const stateActions = initGlobalState({})
this.$stateActions.setGlobalState({ token, mchType, mchId })
父应用配置
main.js (入口文件)
import { registerMicroApps, start } from 'qiankun'
const apps = [
{
name: 'qiankun-sub',
entry: '//localhost:10000',
container: '#main2sub',
// 因为main作为子项目会被注入一个前缀,所以孙子应用sub也要加上这个前缀
activeRule: window.__POWERED_BY_QIANKUN_PARENT__ ? '/main/sub' : '/sub'
}
]
registerMicroApps(apps)
start({
prefetch: false
})
let instance = null
function render(props = {}) {
const { container } = props;
instance = new Vue({
router,
render: (h) => h(App),
}).$mount(container ? container.querySelector('#app') : '#app');
// 后面mount这段是为了处理子应用和孙子应用容器冲突的问题
// 作为微应用时处理传参
if (props && Object.keys(props).length) {
onGlobalStateChange(state => {
const { token, mchType, mchId } = state
token && store.commit('SET_TOKEN', token)
mchType && store.commit('SET_MCH_TYPE', mchType)
mchId && store.commit('SET_MCH_ID', mchId)
}, true)
}
}
// 独立运行时
if (!window.__POWERED_BY_QIANKUN__) {
render();
}
// 解决加载资源是404的问题
if (window.__POWERED_BY_QIANKUN__) {
__webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;
}
// 暴露给父应用的生命周期钩子
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;
}
history模式路由base配置
// 判断是否作为微应用运行,若是,则要加上前缀
const router = new VueRouter({
mode: 'history',
base: window.__POWERED_BY_QIANKUN__ ? '/main' : '/',
routes
})
vue.config.js (打包配置)
const {
name
} = require('./package');
module.exports = {
devServer: {
port: 10001,
headers: {
'Access-Control-Allow-Origin': '*',
},
hot: true
},
configureWebpack: {
output: {
// 把子应用打包成 umd 库格式
library: `${name}-[name]`,
// filename: `${microName}-[name].js`,
libraryTarget: 'umd',
jsonpFunction: `webpackJsonp_${name}`,
// globalObject: 'this',
},
},
publicPath: '/'
}
子应用配置
main.js (入口文件)
let instance = null
function render(props = {}) {
const { container } = props;
instance = new Vue({
router,
render: (h) => h(App),
}).$mount(container ? container.querySelector('#app') : '#app');
}
// 独立运行时
if (!window.__POWERED_BY_QIANKUN__) {
render();
}
// 解决加载资源是404的问题
if (window.__POWERED_BY_QIANKUN__) {
__webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;
}
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;
}
history模式路由base配置
const router = new VueRouter({
mode: 'history',
// 根据全局参数判断自己是作为第几层应用运行,加上对应的前缀,其实这里的前缀也可以在上层应用配置对应的全局参数来传递
base: window.__POWERED_BY_QIANKUN_PARENT__ ? '/main/sub' : window.__POWERED_BY_QIANKUN__ ? '/sub' : '/',
routes
})
vue.config.js (打包配置)
const {
name
} = require('./package');
module.exports = {
devServer: {
port: 10000,
headers: {
'Access-Control-Allow-Origin': '*',
},
hot: true
},
configureWebpack: {
output: {
// 把子应用打包成 umd 库格式,这里和父应用不同的是要把 -[name] 去掉,不然会出现样式丢失的问题
library: `${name}`,
// filename: `${microName}-[name].js`,
libraryTarget: 'umd',
jsonpFunction: `webpackJsonp_${name}`,
// globalObject: 'this',
},
},
publicPath: '/'
}
未完待续...