qiankun微前端主子应用通信方案

2024-08-27 08:58

本文主要是介绍qiankun微前端主子应用通信方案,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、概念

目前有关微前端通信的方案无非两种:

使用qiankun提供的api-initGlobalState进行通信;
通过在主、微应用中定义状态管理类的方式进行通信;

下面我们就第一种方案进行详细讲解,毕竟官方提供了实现方案。达到的效果如下:

主应用作为中转,进行状态承接与派发;
各个微应用不仅能获取主应用的状态变更,还能同步自身状态到主应用;
微应用能独立运行;

二、主应用

我们先来看看initGlobalState(state) 这个api的具体信息:

1.用法:在主应用中使用,定义全局状态,微应用通过props传参获取;
2.返回:
onGlobalStateChange(callback, Immediately)在当前应用监听全局状态变化;
setGlobalState(state)按照一级属性进行状态设置,微应用只能修改一级属性;
offGlobalStateChange()移除当前的状态监听,微应用在unmount时默认调
用;
下面我们在主应用中进行初始化:

import { registerMicroApps, start, setDefaultMountApp, initGlobalState } from 'qiankun'const { onGlobalStateChange } = initGlobalState({iptValue: ''})
onGlobalStateChange((state, prev) => {// state: 变更后的状态; prev 变更前的状态console.log('main-app onGlobalStateChange', state, prev)
})

这里我们只简单定义了一个一级属性iptValue,用于在微应用中绑定表单。同时监听状态变化,打印相关信息。

三、微应用

主应用中状态初始化成功后,整个state状态由qiankun框架内部进行维护,开发者通过官方提供的api进行state的修改、追踪。

因此在每一个微应用中,我们需要做的事情有两个,即:

1.同步主应用状态变化到微应用;
2.同步微应用状态变化到主应用;

下面分别讲解在vue、react中如何进行状态的双向同步。

3.1 vue微应用
我们需要在之前vue入口文件main.js中进行扩展,修改render(props)函数。微应用内部状态管理我们使用vuex,通过vuex提供的api进行状态双向同步。

第一步新建store/index.js文件:

const state = {store: {}
}const getters = {iptValue: state => state.store.iptValue
}const mutations = {initStore(state, data) {state.store = data},setStore(state, data) {state.store = {...state.store,...data}}
}const actions = {}export default {actions,getters,state,mutations,modules: {},strict: false,plugins: [],
}

这里我们只是定义了store的结构,但是并没有生成vuex的实例对象。

第二步初始化微应用store,绑定状态同步逻辑:

import Store from './store/index'/*** 初始化主微应用通信逻辑* 1.主应用状态变更同步到微应用;* 2.微应用状态变更同步到主应用;*/
function initStore(props) {const myPlugin = store => {let prevState = _.cloneDeep(store.state)// 当 store 初始化后调用store.subscribe((mutation, state) => {// 每次 mutation 之后调用let nextState = _.cloneDeep(state)if(JSON.stringify(nextState) !== JSON.stringify(prevState)) {prevState = nextState// 微应用中store变更后,将状态更新到主应用props.setGlobalState &&props.setGlobalState({...state.store})}})}const storeInstance =  new Vuex.Store({...Store,plugins: [myPlugin]})// 主应用状态变化后,同步到微应用props.onGlobalStateChange &&props.onGlobalStateChange((state, prev) => {storeInstance.commit('initStore', state)console.log('vue-app onGlobalStateChange', state, prev)}, true)return storeInstance
}

主应用状态变更同步到微应用比较简单,在onGlobalStateChange方法中调用commit进行同步即可。

微应用状态变更同步到主应用我们使用setGlobalState()方法,关键是要实时监听微应用状态变更。这里我们使用vuex插件提供的派发功能subscribe,同步之前会比较两次状态是否存在变更,否则会陷入死循环。

第三步为vue实例绑定store:

function render(props = {}) {...store = initStore(props)instance = new Vue({router,store,render: h => h(App),}).$mount(container ? container.querySelector('#app') : '#app')
}

这样vue微应用状态同步逻辑就完成了,就像平时使用vuex一样进行管理即可。当然主、微应用通信的这一份状态最好是单独进行维护的,不应该和微应用内部业务逻辑状态相关联,我们可以使用vuex的modules功能进行实现,这里就不再赘诉有需要再更新。

3.2 react微应用
react的实现逻辑和vue都一样,只是不同技术栈代码写法不一样而已,react中我们使用mobx、mobx-react进行状态管理。mobx开箱即用支持装饰器语法,天然存在状态隔离,和react-hook完美搭配。

第一部新建store文件:

import { observable, computed, action, reaction } from 'mobx'
import _ from 'lodash'
import { MainStoreModel } from '../model/mainApp'class MainApp {static setGlobalState: Function@observable preStore: MainStoreModel = {}@observable store: MainStoreModel = {}constructor() {}@computed get iptValue() {return this.store.iptValue}@actioninitStore(data: MainStoreModel) {this.store = data}@actionsetStore(data: any) {const prev = _.cloneDeep(this.store)this.store = {...prev,...data}}
}const mainApp = new MainApp()export { mainApp, MainApp 
}

第二步修改入口文件,初始化state同步逻辑

import { mainApp, MainApp } from './store/mainApp'/*** 初始化主微应用通信逻辑* 1.主应用状态变更同步到微应用;* 2.微应用状态变更同步到主应用;*/
function initStore(props: any) {// 将setGlobalState方法绑定到类MainApp静态属性上MainApp.setGlobalState = props.setGlobalState ? props.setGlobalState : null// 主应用状态变更同步到微应用props.onGlobalStateChange &&props.onGlobalStateChange((state: MainStoreModel, prev: MainStoreModel) => {mainApp.initStore(state)console.log('react-app onGlobalStateChange', state, prev)}, true)
}export async function mount(props: any) {render(props)
+  initStore(props)
}

主应用状态同步到微应用逻辑和vue大同小异。不同的是,我们将setGlobalState方法绑定在MainApp类的静态属性上,微应用状态同步到主应用时会用到。

第三步reaction同步微应用状态到主应用

我们使用mobx中reaction的特性用于监听store的变化,来实现我们需要的逻辑。

class MainApp {  ...appReaction = reaction(() => this.store,store => {const nextState = _.cloneDeep(store)const prevState = _.cloneDeep(this.preStore)if(JSON.stringify(nextState) !== JSON.stringify(prevState)) {MainApp.setGlobalState&&MainApp.setGlobalState(nextState)this.preStore = nextState}})
}

同步逻辑同样需要比较变更前后两份深拷贝状态的差异,防止陷入死循环。

这篇关于qiankun微前端主子应用通信方案的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1111214

相关文章

C语言中位操作的实际应用举例

《C语言中位操作的实际应用举例》:本文主要介绍C语言中位操作的实际应用,总结了位操作的使用场景,并指出了需要注意的问题,如可读性、平台依赖性和溢出风险,文中通过代码介绍的非常详细,需要的朋友可以参... 目录1. 嵌入式系统与硬件寄存器操作2. 网络协议解析3. 图像处理与颜色编码4. 高效处理布尔标志集合

Java Response返回值的最佳处理方案

《JavaResponse返回值的最佳处理方案》在开发Web应用程序时,我们经常需要通过HTTP请求从服务器获取响应数据,这些数据可以是JSON、XML、甚至是文件,本篇文章将详细解析Java中处理... 目录摘要概述核心问题:关键技术点:源码解析示例 1:使用HttpURLConnection获取Resp

Java中的Lambda表达式及其应用小结

《Java中的Lambda表达式及其应用小结》Java中的Lambda表达式是一项极具创新性的特性,它使得Java代码更加简洁和高效,尤其是在集合操作和并行处理方面,:本文主要介绍Java中的La... 目录前言1. 什么是Lambda表达式?2. Lambda表达式的基本语法例子1:最简单的Lambda表

Java实现优雅日期处理的方案详解

《Java实现优雅日期处理的方案详解》在我们的日常工作中,需要经常处理各种格式,各种类似的的日期或者时间,下面我们就来看看如何使用java处理这样的日期问题吧,感兴趣的小伙伴可以跟随小编一起学习一下... 目录前言一、日期的坑1.1 日期格式化陷阱1.2 时区转换二、优雅方案的进阶之路2.1 线程安全重构2

HTML5中的Microdata与历史记录管理详解

《HTML5中的Microdata与历史记录管理详解》Microdata作为HTML5新增的一个特性,它允许开发者在HTML文档中添加更多的语义信息,以便于搜索引擎和浏览器更好地理解页面内容,本文将探... 目录html5中的Mijscrodata与历史记录管理背景简介html5中的Microdata使用M

html5的响应式布局的方法示例详解

《html5的响应式布局的方法示例详解》:本文主要介绍了HTML5中使用媒体查询和Flexbox进行响应式布局的方法,简要介绍了CSSGrid布局的基础知识和如何实现自动换行的网格布局,详细内容请阅读本文,希望能对你有所帮助... 一 使用媒体查询响应式布局        使用的参数@media这是常用的

HTML5表格语法格式详解

《HTML5表格语法格式详解》在HTML语法中,表格主要通过table、tr和td3个标签构成,本文通过实例代码讲解HTML5表格语法格式,感兴趣的朋友一起看看吧... 目录一、表格1.表格语法格式2.表格属性 3.例子二、不规则表格1.跨行2.跨列3.例子一、表格在html语法中,表格主要通过< tab

Python结合PyWebView库打造跨平台桌面应用

《Python结合PyWebView库打造跨平台桌面应用》随着Web技术的发展,将HTML/CSS/JavaScript与Python结合构建桌面应用成为可能,本文将系统讲解如何使用PyWebView... 目录一、技术原理与优势分析1.1 架构原理1.2 核心优势二、开发环境搭建2.1 安装依赖2.2 验

Java字符串操作技巧之语法、示例与应用场景分析

《Java字符串操作技巧之语法、示例与应用场景分析》在Java算法题和日常开发中,字符串处理是必备的核心技能,本文全面梳理Java中字符串的常用操作语法,结合代码示例、应用场景和避坑指南,可快速掌握字... 目录引言1. 基础操作1.1 创建字符串1.2 获取长度1.3 访问字符2. 字符串处理2.1 子字

Vue3组件中getCurrentInstance()获取App实例,但是返回null的解决方案

《Vue3组件中getCurrentInstance()获取App实例,但是返回null的解决方案》:本文主要介绍Vue3组件中getCurrentInstance()获取App实例,但是返回nu... 目录vue3组件中getCurrentInstajavascriptnce()获取App实例,但是返回n