首页 > 其他分享 >qiankun实现主应用与微应用间通信的常用方式

qiankun实现主应用与微应用间通信的常用方式

时间:2024-11-29 22:28:30浏览次数:6  
标签:qiankun initGlobalState app actions 间通信 应用 props

上篇文章(qiankun+vite+vue3从零搭建一个微前端架构系统)讲了如何从0搭建一个基于qiankun的微前端架构,这篇文章将探索一下主应用与微应用之间如何实现通信,代码是在上篇文章基础上改的。

一、qiankun 提供的 initGlobalState 方法

1. initGlobalState简介

qiankun中,initGlobalState是用于创建一个全局状态对象的方法。这个全局状态对象可以在主应用和子应用之间共享数据,它基于mitt库实现了一个简单的事件总线机制。通过这个全局状态对象,不同的应用(主应用和子应用)可以进行数据的传递和共享,并且能够响应数据的变化。

2. 在主应用中使用initGlobalState实现通信的步骤

2.1 创建和初始化全局状态对象

新建一个actions.ts文件(src/actions.ts),在这里初始化state,监听全局状态改变

import { initGlobalState, type MicroAppStateActions } from "qiankun";

// 初始化 state
const state = {
    testId: null,
};
export const actions: MicroAppStateActions = initGlobalState(state);

// 监听全局状态
actions.onGlobalStateChange((state, prev) => {
    // state: 变更后的状态; prev 变更前的状态
    console.log('onGlobalStateChange', state, prev);
});

2.2 在主应用main.ts加载子应用生命周期的时候可以改变状态
registerMicroApps(
    ...
    {
        afterMount: ((app) => {
            console.log('main app afterMount', app);
            actions.setGlobalState({ testId: 11111 });
            return Promise.resolve();
        })
    }
)

3 在子应用中使用initGlobalState实现通信的步骤

3.1 子应用中新建src/actions.ts
function emptyAction(...args: any[]) {
    // 警告:提示当前使用的是空 Action
    window.console.warn('Current execute action is empty!');
}

// 创建一个Action类
class Actions {
    // 默认值为空 Action
    actions = {
        onGlobalStateChange: emptyAction,
        setGlobalState: emptyAction,
    };

    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;
3.2 子应用加载后,render的时候能拿到主应用传来的action
import actions from './actions';
function render(props?: { container: HTMLElement; onGlobalStateChange: () => void; setGlobalState: () => void; }) {
    if (props) {
        actions.setActions(props); //设置action
    }

    microRouter = router;
    app = createApp(App);
    app.use(microRouter);
    app.use(ElementPlus);
    app.mount(props?.container ? props?.container.querySelector('#container') : '#container');
}

3.3 子应用中修改全局状态

在子应用的App.vue文件中加一个按钮,点击的时候改变全局状态,主应用就能监听到数据改变。

<script setup lang="ts">
import { RouterLink, RouterView } from 'vue-router'
import HelloWorld from './components/HelloWorld.vue'
import actions from './actions';

const click = () => {
    actions.setGlobalState(
        {
            testId: 555555555
        }
    )
}
</script>

<template>
    <header>
        <h2>我的微应用</h2>
        <el-button @click="click">点击向主应用传递数据</el-button>
    </header>

    <RouterView />
</template>

最后我们在页面上点一下,就能在控制台看到主应用监听处的log打印出来了。
在这里插入图片描述

通过initGlobalState方法,主应用和子应用之间可以方便地共享和更新全局状态,实现有效的通信。这种方式使得在微前端架构下,不同的应用之间能够更好地协同工作。

二、props属性

上篇文章,在主应用中注册子应用的时候我只配置几个必须的属性,他其实还能配置一个props属性,可以通过这种方式向子应用传数据,在子应用mount之后就能拿到数据
{
  name: 'silvia-micro', // app name registered
  entry: '//localhost:5174', // 微应用的出口地址
  container: '#container', // 微应用挂载的容器id
  activeRule: '/silvia-micro', // 微应用激活路由规则
  props: {
     mainInfo: {
       name: 'zhangsan'
     }
 }
}
需要注意的是,使用props通信还是有点限制的:

单向数据流限制props通常遵循单向数据流原则,即从主应用流向子应用。这在一定程度上限制了子应用对数据的更新方式。如果子应用需要更新props中的数据,不能直接修改,而是需要通过回调函数或者其他方式通知主应用进行修改。例如,子应用内部发生了一个事件,需要更新props中的某个用户信息,它可能需要触发一个由主应用传入的回调函数来实现更新。这种间接的更新方式增加了代码的复杂性和理解成本。

实时性和一致性挑战:当主应用中的数据发生变化并通过props传递给子应用时,确保子应用能够及时、准确地更新数据可能会比较复杂。尤其是在多个子应用同时依赖相同props数据的情况下,很难保证数据更新的实时性和一致性。例如,主应用更新了一个全局配置props,但由于网络延迟或者子应用内部的其他异步操作,不同子应用可能会在不同时间点接收到更新后的props,导致数据不一致的情况。

三、基于自定义事件通信

原理:利用浏览器的事件机制,主应用和微应用可以通过发布 / 订阅自定义事件来传递消息。例如,主应用可以发布一个事件,微应用订阅这个事件并在事件触发时执行相应的操作,反之亦然。

  • 主应用App.vue文件:
const event = new CustomEvent('microAppMessage', {
    detail: {
        message: '这是主应用发送的消息'
    }
});

const click = () => {
    window.dispatchEvent(event);
}
  • 子应用App.vue文件
window.addEventListener('microAppMessage', (event) => {
    console.log('微应用收到消息:', event);
});
  • 然后运行在页面上点击按钮,向子应用发送消息,控制台就能看到子应用收到了。

在这里插入图片描述

这里呢就先演示这三种方式,当然还有其他方法,比如基于URL通信,本地存储等方式,但是工作中一般最常用的还是官方提供的initGlobalState方式,作为 qiankun 框架自身提供的功能,它与 qiankun 的其他机制(如微应用的加载、生命周期管理等)能够很好地集成。这种原生支持意味着开发者不需要引入额外复杂的第三方状态管理库,减少了因库冲突或不兼容带来的风险。

标签:qiankun,initGlobalState,app,actions,间通信,应用,props
From: https://blog.csdn.net/weixin_43162494/article/details/144147037

相关文章

  • 空壳应用分身 一款强大的分身软件
    空壳分身是一款功能强大的应用分身工具,支持主流应用的多开功能,用户可以在同一部手机上创建多个相同应用的分身,如微信、QQ等,满足用户多账号管理的需求。每个分身应用都可以独立运行,互不干扰,且拥有独立的应用权限设置,保障用户隐私和数据安全。界面布局简洁明了,用户可以轻松上手,......
  • vsftpd 的安装和应用(超详细!!!)
            FTP(FileTransferProtocol,文件传输协议)是一种用于在计算机网络上进行文件传输的标准协议。它允许用户从一台计算机向另一台计算机上传或下载文件。FTP的工作原理涉及到客户端和服务器之间的交互,以及数据传输的过程。一、FTP的工作流程        当FTP......
  • 【Elasticsearch】容器日志管理:提升容器化应用运维效率
    ......
  • 【泛微E9】移动应用将页面按钮置灰
    效果如下:实现方法:$load(function(){setTimeout(function(){varkpbm=$f("kpbm").val();varzcbm=$f("zcbm").val();constdate=newDate();constyear=date.getFullYear();......
  • Pandas教程之十三:在DataFrame中应用函数
    Python是一种执行数据分析任务的优秀语言。它提供了大量的类和函数,有助于更轻松地分析和处理数据。在本文中,我们将了解如何将函数应用于PandasDataframe中的每一行。将函数应用于PandasDataFrame中的每一行有多种方法可以对DataFrame列执行逐元素操作。这里我们讨论......
  • 腾讯云 AI 代码助手:单元测试应用实践
    引言在软件开发这一充满创造性的领域中,开发人员不仅要构建功能强大的软件,还要确保这些软件的稳定性和可靠性。然而,开发过程中并非所有任务都能激发创造力,有些甚至是重复且乏味的。其中,编写单元测试无疑是最令人头疼的任务之一,它虽然对于验证软件组件是否按预期工作至关重要,但其编......
  • 高德应用OceanBase云数据库的升级选型与迁移干货
    业务背景高德,DAU已在亿级,时时刻刻都持续不断地产生着庞大的数据。随着数据量的迅猛增长,对现有的业务数据存储能力构成日益严峻的挑战。以我所在部门中的某一大型服务为例,其存储在XDB中的数据量往往达到数百TB之巨,且TPS(包括QPS)维持在万级水平。如何高效地管理这些数据,并在保证......
  • 2025蓝桥杯(单片机)备赛--扩展外设之PWM的原理与应用(十三)
    1PWM原理        PWM:该方法未使用常规的PWM相关的寄存器配置;而是使用了定时器2;与这个类似。周期:通过定时器2设置每次进中断的间隔,来设置最小周期(步进),如设置100us,这时PWM的最小周期为100us,最大频率为1/100us;可通过设置一个变量进行累加,当该变量的值达到一定......
  • 【Python入门】绘制你的桌面应用:用Python WxPython库打造用户界面
    ......
  • C# OxyPlot在WinForms中的面积图应用指南:数据可视化的艺术
    在C#的WinForms应用中,数据可视化是一个重要的领域,而OxyPlot作为一个强大的跨平台绘图库,提供了丰富的图表类型和高度的可定制性。本文将带你深入了解如何在WinForms中使用OxyPlot来创建和操作面积图,让你的数据展示更加直观和专业。OxyPlot简介OxyPlot是一个开源的.NET绘图......