qiankun 内实现应用通讯的三种方式(props、initGlobalState、socket.io)

qiankun 内实现应用通讯的三种方式(props、initGlobalState、socket.io),第1张

目录

1. props

1.1 主应用中定义 props

1.2 微应用中获取 props

2. initGlobalState(state) 

2.1 基本使用说明

2.1.1 参数

2.1.2 用法

2.1.3 返回(返回 MicroAppStateActions 实例)

2.1.4 官方示例

2.2 initGlobalState(state) 通信原理

3. 实战

3.1 主应用

3.1.1 注册 MicroAppStateActions 实例

3.1.2 使用 MicroAppStateActions 实例

3.2 微应用

3.2.1 在 main.ts 中接收参数

3.2.2 在实际业务相关的 .vue 文件中使用参数

4. socket.io

5. 通信方式对比

5.1 使用 props 进行通信

5.2 使用 qiankun 提供的 API initGlobalState 进行通信

5.3 使用外部插件 socket.io 进行通信


1. props 1.1 主应用中定义 props

在主应用中,注册微应用的基础配置信息时,定义 props ,编写需要传递给微应用的信息

如下代码所示,props 中添加了给微应用传递的参数

window.microApp = [
  {
    name: 'micro-app', // 唯一值。建议和 package.json 中的 name 一致
    entries: {
      dev: '//localhost:8081/', // 开发环境
      product: '//xxx.xxx.x.xxx:8104/vue3-backstage-micro-app/', // 线上
    },
    container: '#micro-app', // 容器 ID
    activeRule: getActiveRule('#/vue'), // 激活路径
    props: {
      id: 'props 传值方式'
    },
  },
];

1.2 微应用中获取 props

微应用在 qiankun 框架的 mount 生命周期里,可以获取 props

由于在 mount 生命周期里,调用了 render() 函数,所以在 render 中要定义接收 props 的参数

function render(props?: any) {
  console.log(props?.id);
}
...

// 生命周期
....
export async function mount(props): Promise {
  render(props);
}
...

打印结果:

2. initGlobalState(state)  2.1 基本使用说明

initGlobalState() 是 qiankun 提供的通信 API

API 说明 - qiankunhttps://qiankun.umijs.org/zh/api#initglobalstatestate

2.1.1 参数

state - Record - 必选

2.1.2 用法

定义全局状态,并返回通信方法,建议在主应用使用,微应用通过 props 获取通信方法

2.1.3 返回(返回 MicroAppStateActions 实例)

在当前应用监听全局状态,有变更触发 callback,fireImmediately = true 立即触发 callback

onGlobalStateChange: (callback: OnGlobalStateChangeCallback, fireImmediately?: boolean) => void

按一级属性设置全局状态,微应用中只能修改已存在的一级属性

setGlobalState: (state: Record) => boolean

移除当前应用的状态监听,微应用 umount 时会默认调用

offGlobalStateChange: () => boolean

2.1.4 官方示例

主应用:

import { initGlobalState, MicroAppStateActions } from 'qiankun';

// 初始化 state
const actions: MicroAppStateActions = initGlobalState(state);

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

微应用:

// 从生命周期 mount 中获取通信方法,使用方式和 master 一致
export function mount(props) {
  props.onGlobalStateChange((state, prev) => {
    // state: 变更后的状态; prev 变更前的状态
    console.log(state, prev);
  });

  props.setGlobalState(state);
}

2.2 initGlobalState(state) 通信原理

qiankun 内部提供了 initGlobalState 方法,用于注册 MicroAppStateActions 实例

MicroAppStateActions 实例包含了三个用于应用通信的方法:

onGlobalStateChange:注册 观察者 函数 - 响应 globalState 变化,在 globalState 发生改变时触发该 观察者 函数。setGlobalState:设置 globalState - 设置新的值时,内部将执行 浅检查,如果检查到 globalState 发生改变则触发通知,通知到所有的 观察者 函数【深度监听的】offGlobalStateChange:取消 观察者 函数 - 该实例不再响应 globalState 变化

综上所述: 

每个应用都可以注册 观察者 到观察者池中每个应用都可通过修改 globalState,触发所有的 观察者 函数,实现应用通信

3. 实战

场景:主应用登录后,需要给各个微应用传递登录后获得的 token

3.1 主应用 3.1.1 注册 MicroAppStateActions 实例
import {
  registerMicroApps,
  start,
  initGlobalState
  MicroAppStateActions,
} from 'qiankun';

....

// 注册微应用通信示例
const initialState = {};
const actions: MicroAppStateActions = initGlobalState(initialState);

export {
  start, // 导出 qiankun 的启动函数
  actions, // 导出通信示例
}

3.1.2 使用 MicroAppStateActions 实例

在登录页面中,使用 3.1.1 定义的 MicroAppStateActions 实例:

注册 观察者 函数:actions.onGlobalStateChange((state, prevState) => { ... })触发 观察者 函数:actions.setGlobalState({ ... })【深度监听的】



3.2 微应用

在 3.1 中,主应用内获取的 token 已经被记录在了 globalState 中,接下来要在微应用中获取它

3.2.1 在 main.ts 中接收参数
function render(props?: any) {
  if (props) {
    /**
     * 注册一个观察者函数
     * @param state 变更后的状态
     * @param prevState: 变更前的状态
     */
    props.onGlobalStateChange(
      (state: { token: any }, prevState: { token: any }) => {
        // state: 变更后的状态; prevState: 变更前的状态
        console.log("微应用观察者:token 改变前的值为 ", prevState.token);
        console.log("微应用观察者:token 改变后的值为 ", state.token);
      }
    );
  }
}

// 生命周期
export async function mount(props): Promise {
  render(props);
}

3.2.2 在实际业务相关的 .vue 文件中使用参数

第一步:新建 /hooks/actions.ts,存放全局使用通信的实例方法

function emptyAction(...args: any[]) {
  // 警告:提示当前使用的是空 Action
  console.warn("Current execute action is empty!");
}

class Actions {
  // 默认值为空 Action
  actions = {
    onGlobalStateChange: emptyAction,
    setGlobalState: emptyAction,
  };

  /**
   * 设置 actions
   */
  setActions(actions: {
    onGlobalStateChange: () => void;
    setGlobalState: () => void;
  }) {
    this.actions = actions;
  }

  /**
   * 映射
   */
  onGlobalStateChange(...args: any[]) {
    return this.actions.onGlobalStateChange(...args);
  }

  /**
   * 映射
   */
  setGlobalState(...args: any[]) {
    return this.actions.setGlobalState(...args);
  }
}

const actions = new Actions();
export default actions;

第二步:在入口文件引入 /hooks/actions.ts ,并为其注入真实 Actions

function render(props?:any) {
  if (props) {
    // 注入 actions 实例
    actions.setActions(props);
  }
	...
}

// 生命周期
export async function mount(props): Promise {
  render(props);
}

第三步:在需要用到通信参数的 vue 页面里,引入 /hooks/actions.ts,并进行监听


打印结果:

解释如下: 

主应用登录前:token = undefined
主应用登录后:token = 时间111

微应用加载前:token = undefined
微应用加载后:token = 时间111(被主应用传递过来的)

微应用内改变了 token 后,主应用和微应用同时触发了观察者数 actions.onGlobalStateChange;
改变前,主应用微应用中的 token = 时间111;
改变后,主应用微应用中的 token = 时间222;

4. socket.io

暂无示例

5. 通信方式对比 5.1 使用 props 进行通信

优点:

使用简单适合初次加载微应用时传递消息

缺点:

微应用独立运行时,无法使用微应用需要先了解状态池的内容,再进行通信微应用挂载后,不能实时监听

5.2 使用 qiankun 提供的 API initGlobalState 进行通信

优点:

使用简单,官方支持性高适合通信较少的业务场景可实现实时监听

缺点:

微应用独立运行时,无法使用微应用需要先了解状态池的内容,再进行通信

5.3 使用外部插件 socket.io 进行通信

优点:

微应用不受主应用影响,可以独立运行不限使用场景可实现实时监听

缺点:

需要写服务端代码不会使用的,需要学习成本

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1296337.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-10
下一篇 2022-06-10

发表评论

登录后才能评论

评论列表(0条)

保存