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}`
        },
    },
}

 

posted @ 2023-03-23 16:30  wjs0509  阅读(1246)  评论(0编辑  收藏  举报