qiankun 实现父子应用通信

前言:

最近有一个项目在实现微前端,把几个独立的项目集成一个项目里,选择了qiankun技术栈。
qinakun 官网 使用指南

使用时遇到了 主应用(父),子应用之间需要传递消息。特此记录一下。

实现过程:

我找了一下,实现 通信的方式挺多的 props、第三方库 比如 vuex\redux等等、官方提供的 initGlobalState 、 本地存储(sessionStorage\localStorage)。其他通信方式可参考:
微前端:qiankun的五种通信方式
如果简单的通信可以用 本地存储实现这个 很快。

我选择了官方提供的 initGlobalStat API,原因是我需要接入 4个子系统,不能 每个都用第三方库。实际上 initGlobalState 也是借助了 props实现。

initGlobalState 文档

在主应用里 的入口文件 或者注册微应用 的文件里写上:

import {
    
     initGlobalState } from 'qiankun';

let state={
    
    
  message:"123"
}
// 初始化 state
const actions = initGlobalState(state);

actions.onGlobalStateChange((state, prev) => {
    
    
  // state: 变更后的状态; prev 变更前的状态
  console.log(state, prev);
});
actions.setGlobalState(state);
//actions.offGlobalStateChange();

需要注意的是 把 actions.offGlobalStateChange(); 这行注释掉。否则无法完成通信。

子应用里需要 从生命周期 mount 中获取通信方法 。这个生命周期需要写在 入口文件(一般是 app.js\main.js\index.js等等)。

因为我的子应用里 没有入口文件 所以 需要在src下新建一个 app.js。然后写上:

export const qiankun = {
    
    

  // 应用加载之前
  async bootstrap(props) {
    
    
    console.log('子应用初始化1', props);
  },

  // 应用 render 之前触发
  async mount(props) {
    
    
    if(props){
    
     //把 qiankun 的props 挂载到全局变量
      window.qiankunProps=props;
    }
  },

  // 应用卸载之后触发
  async unmount(props) {
    
    
    console.log('子应用已卸载1', props);
  },
};

在这里插入图片描述

umi qiankun 子应用配置生命周期钩子
上面的写法是 umi框架的写法,因为我的项目基于umi所以用的是上面这种写法。

其他框架就可以按照官方文档写:

/**
 * bootstrap 只会在微应用初始化的时候调用一次,下次微应用重新进入时会直接调用 mount 钩子,不会再重复触发 bootstrap。
 * 通常我们可以在这里做一些全局变量的初始化,比如不会在 unmount 阶段被销毁的应用级别的缓存等。
 */
export async function bootstrap() {
    
    
  console.log('react app bootstraped');
}

/**
 * 应用每次进入都会调用 mount 方法,通常我们在这里触发应用的渲染方法
 */
export async function mount(props) {
    
    
  if(props){
    
     //把 qiankun 的props 挂载到全局变量
      window.qiankunProps=props;
    }
}

/**
 * 应用每次 切出/卸载 会调用的方法,通常在这里我们会卸载微应用的应用实例
 */
export async function unmount(props) {
    
    
 
}

/**
 * 可选生命周期钩子,仅使用 loadMicroApp 方式加载微应用时生效
 */
export async function update(props) {
    
    
  console.log('update props', props);
}

截图

具体参考:qiankun微应用 导出相应的生命周期钩子

qiankunProps需要全局使用,我选择挂载到window上,如果你是vue的话 可以直接挂载到 vue实例上。Vue.$qinakun=xxx。

然后 在其他页面就可以使用window?.qiankunProps?.setGlobalState发送消息 :

 window?.qiankunProps?.setGlobalState({
    
    
   message:"子应用发送的消息"
 })
    

如果 你有入口文件,则可以直接在入口文件里写上 声明周期方法 ,不需要新建 文件了。不过 新建一个文件 在 入口文件引入 执行也可以(分模块 看起来更清晰)。

如何 验证是否 通信成功了?

只需要看控制台 主应用里 onGlobalStateChange 里打印的结果即可 默认会打印一下默认值。触发setGlobalState 后会再次打印,打印的值是传入的值,即通信成功。
在这里插入图片描述

遇到的问题:

本地 启动子应用可以,通信,生命周期都走了。但 子应用一打包 生命周期就不运行了。

需要 子应用 打包时的webpack配置一下:
webpack:
webpack v5:



const packageName = require('./package.json').name;

module.exports = {
    
    
  output: {
    
    
    library: `${
      
      packageName}-[name]`,
    libraryTarget: 'umd',
    chunkLoadingGlobal: `webpackJsonp_${
      
      packageName}`,
  },
};

webpack v4:

const packageName = require('./package.json').name;

module.exports = {
    
    
  output: {
    
    
    library: `${
      
      packageName}-[name]`,
    libraryTarget: 'umd',
    jsonpFunction: `webpackJsonp_${
      
      packageName}`,
  },
};

其他打包工具,官网没给,但原理差不多,需要自行查文档。
具体可参考:
配置微应用的打包工具

如果报:Application died in status LOADING_SOURCE_CODE: You need to export the functional lifecycles in xxx entry。
可以参考:
Application died in status LOADING_SOURCE_CODE: You need to export the functional lifecycles in xxx entry

建议遇到问题优先查看文档:
qiankun 官方文档
qiankun 官方文档 常见问题

我还遇到了,样式冲突,按照文档里 常见问题的解决方案就可以解决。 样式隔离,比如 我主应用用了antd,子应用也用了。就会有样式冲突。
如何确保主应用跟微应用之间的样式隔离

猜你喜欢

转载自blog.csdn.net/weixin_44058725/article/details/138998513