qiankun多重应用嵌套(父 --> 子 --> 孙)
父子孙应用路由都是使用的history模式
父应用配置:
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() // 给微应用传参 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': '*', } }, configureWebpack: { output: { // 把子应用打包成 umd 库格式 library: `${name}-[name]`, libraryTarget: 'umd', jsonpFunction: `webpackJsonp_${name}` }, }, 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': '*', } }, configureWebpack: { output: { // 把子应用打包成 umd 库格式,这里和父应用不同的是要把 -[name] 去掉,不然会出现样式丢失的问题 library: `${name}`, libraryTarget: 'umd', jsonpFunction: `webpackJsonp_${name}` }, }, }