qiankun微前端学习笔记

139 阅读2分钟

qiankun嵌入子应用流程

  1. 注册子应用
import { addGlobalUncaughtErrorHandler, registerMicroApps } from 'qiankun'
// 构建子应用对象数组
const apps = [
        {
            name: 'sub1', // 子应用有唯一性 这个需要与子应用的webpackname一致
            entry: 'xxxxxxxxxx', // 子应用入口 通过该地址加载子应用
            container: '#subapp', // 子应用挂载的节点 子应用加载完成后将挂载在这个节点上
            activeRule: '/#/sub1', //子应用触发的路由规则 触发路由规则后将加载该子应用
            props: msg, // 共享数据的到子应用
            sandbox:{
                strictStyleIsolation:true,
            } // 开启沙箱
        },
        {
            name: 'sub2',
            entry: '//xxxxxxxxxx',
            container: '#subapp',
            activeRule: '/#/sub2',
            props: msg // 共享数据的到子应用
        }
    ]
// 注册子应用
registerMicroApps(apps, {
  // 挂载前的回调  
  beforeLoad: (app) => {
    return Promise.resolve()
  },
  // 挂载后的回调  
  beforeMount: (app) => {
    return Promise.resolve()
  },
  // 卸载前的回调  
  afterMount: (app) => {
    return Promise.resolve()
  },
  // 卸载后的回调 
  afterUnmount: (app) => {
    return Promise.resolve()
  }
})
// 监听并处理在子应用生命周期内发生的未被捕获的异常和错误
addGlobalUncaughtErrorHandler((event) => {
  const { message: msg } = event
  if (msg && msg.includes('died in status LOADING_SOURCE_CODE')) {
    console.error('微应用加载失败,请检查应用是否可运行')
  }
})
  1. 配置子应用路由规则
const router = createRouter({
	history: createWebHashHistory(),
	routes: [{
            path: '/sub1',
            name: 'sub1',
            component: () => import('index.vue'),
            meta: {
                title: 'sub1'
            },
            children: [
                {
                    path: '/sub1/:id/:id',
                    component: () => import('index.vue')
                 },
                {
                    path: '/sub1/:id/:id',
                    component: () => import('index.vue')
                 },
             ]
         },
         {
            path: '/sub2',
            name: 'sub2',
            component: () => import('index.vue'),
            meta: {
                title: 'sub2'
            },
            children: [
                {
                    path: '/sub2/:id/:id',
                    component: () => import('index.vue')
                 },
                {
                    path: '/sub2/:id/:id',
                    component: () => import('index.vue')
                 },
             ]
         }]
     })

qiankun主应用与子应用通讯方式

// ---------- 主应用 ----------
import { initGlobalState } from 'qiankun'

const initialState = { msg:数据1 } // 定义一个观察池
const actions = initGlobalState(initialState) // 初始化state
// 在当前应用内监听全局状态 有变更触发回调
actions.onGlobalStateChange((state, prev) => {
        console.log('变更前的状态---',prev)
	console.log('变更后的状态---',state)
})
// 设置全局状态 子应用中只能修改已存在的属性
actions.setGlobalState(state)
// 移除当前应用的状态监听 子应用unmount时会默认调用
actions.offGlobalStateChange()
// 可以直接将actions导出
export default actions

// ---------- 子应用 ----------
// 从生命周期函数mount中获取通信方法 使用方法和主应用一致
export function mount(props) {
    // 监听全局状态
    props.onGlobalStateChange(state,prev) => {
        consloe.log('变更前的状态---',prev)
        console.log('变更后的状态---',state)
    }
    // 修改状态池中的属性
    props.setGlobalState(state)
}

子应用的生命周期函数

/**
 * bootstrap只会在子应用初始化的时候调用一次 下次子应用重新进入时会直接调用mount钩子不会重复触发bootstrap
 */
export function bootstrap() {
    // 通常会在这里做一些全局变量的初始化 比如不会在unmount阶段被销毁的应用级别的缓存等
    console.log('bootstrap函数')
}
/**
 * mount应用每次进入都会调用 通常会在这里触发应用的渲染方法
 */
export function mount(props) {
    // props 由主应用传递过来,如container(渲染节点) 
    const container = props.container || '#app' // 默认挂载点为#app 
    app.$mount(container);
}
/**
 * unmount应用每次切出/卸载的时候会调用 通常在这里会卸载子应用的应用实例
 */
export function unmount(props) { 
    const container = props.container ? props.container.querySelector('#root') : document.getElementById('root')
    // 获取挂载在该DOM节点上的Vue实例 
    const appInstance = container.__vue__
    if (appInstance) { 
        // 卸载并清理Vue实例 
        appInstance.$destroy() 
    } 
}