微前端:qiankun的五种通信方式

news2024/9/20 18:43:21

背景

今天盘点一下 qiankun 父子应用的通信方式都有哪些,我发现了 5 种。

1、localStorage/sessionStorage
2、通过路由参数共享
3、官方提供的 props
4、官方提供的 actions
5、使用vuex或redux管理状态,通过shared分享

接下来我们一个一个进行说明

1、localStorage/sessionStorage

有人说这个方案必须主应用和子应用是同一个域名下。其实不是的,子应用使用不同的域名也是可以的,因为在 qiankun 中,主应用是通过 fetch 来拉取子应用的模板,然后渲染在主应用的 dom 上的,说白了还是运行在主应用上,所以还是运行在同一个域名上,也就是主应用的域名。

父传子

主应用 main.js

localStorage.setItem('token', '123')
console.log('在main中设置了token')

子应用app1 main.js

const token = localStorage.getItem('token')
console.log('app1中打印token:', token)

我们可以看到,从主应用的首页跳到微应用 app1 的首页,分别打印了这两项,说明是可以通过 localstorage 通信的。
在这里插入图片描述

子传父

同理app1修改token,main也可以看到,这里就不再赘述

2、通过路由参数共享

这个也很好理解,因为只有一个 url,不过子应用还是主应用给 url 上拼接一些参数,那么父子应用都可以通过 route 来获取到。

父传子

这里我没有找到父传子的场景

子传父

主应用跳到子应用,子应用内部路由跳转携带参数,父应用通过路由守卫可以拿到路由上的参数。
在这里插入图片描述

从 main 首页跳到 app1 首页,app1 首页点击列表跳到了 app1 的详情页,可以看到详情页的 url 上分别带了两个参数,而路由跳转的时候触发了 main 的路由守卫,捕获到了这个路由。

可以看到这里的 meta 和 name 是空的,但是我子应用明明有设置啊,这是怎么回事?

其实捕获到的路由对象是主应用的,而不是子应用的,这里能获取到这两个参数,完全是因为路由守卫获取的时候只关心 url 的 ? 后面的参数,所以这里碰巧共享了。

如果父应用想完整的获取子应用的路由怎么获取呢?
只能通过其他传值方式将子应用的路由对象传给父应用了。
把父应用的路由实例传给子应用,也是没用的,大家可以不用尝试了。

3、官方提供的 props

上一篇文章 微前端:qiankun的两种运作模式 介绍了qiankun 的两种运作模式,而这两种模式都提供了一个参数 props。

父传子

我们以一个例子来示范一下,这个例子是父应用把父路由的实例传递给子应用。

父应用:

import {
  registerMicroApps,
  start,
} from "qiankun";
import router from '@/router'
const apps = [
  {
    name: "App1MicroApp",
    entry: '//localhost:9001',
    container: "#app1",
    activeRule: "/app1",
    props: {
      parentRouter: router
    }
  }
];

registerMicroApps(apps);
start();

子应用:

let instance = null
let router = null

function render (props) {
  router = new VueRouter({
    base: window.__POWERED_BY_QIANKUN__ ? '/app1' : '',
    mode: 'history',
    routes: routes
  })
  instance = new Vue({
    router,
    store,
    // 挂载在根节点上
    data(){
      return {
        parentRouter: props.parentRouter,
      }
    },
    render: (h) => h(App)
  }).$mount('#app')
}

export async function mount(props) {
  render(props);
}

// 在子应用中使用就可以访问到这个parentRouter了
this.$root.parentRouter

子传父

同理,传进来一个函数或者对象等,子应用操作这个对象就是改变的父应用的状态。
类似 react 的通信方式。

4、官方提供的 actions

就一个 API initGlobalState(state)
参数:传入你维护的一个 state,类似 store 中的 state
返回:action 实例,并挂载了三个函数
1、onGlobalStateChange: (callback: OnGlobalStateChangeCallback, fireImmediately?: boolean) => void, 在当前应用监听全局状态,有变更触发 callback,fireImmediately = true 立即触发 callback

2、setGlobalState: (state: Record<string, any>) => boolean, 可以在应用中任何地方调用来修改全局状态,子应用想使用的话可以通过 props 把 action 传给子应用使用

3、offGlobalStateChange: () => boolean,移除当前应用的状态监听,微应用 umount 时会默认调用

父传子

主应用:
src/micro/actions.ts

import { initGlobalState, MicroAppStateActions } from 'qiankun';

const state = {
  num: 1
};

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

actions.onGlobalStateChange((state, prev) => {
  // state: 变更后的状态; prev 变更前的状态
  console.log('主应用检测到state变更:', state, prev);
});

// 你还可以定义一个获取state的方法下发到子应用
actions.getGlobalState = function () {
  return state
}

export default actions;

当然,父应用也可以自己通过这个 actions 来调用 setGlobalState 函数改变全局状态 state

src/micro/index.js

import {
  registerMicroApps,
  start,
} from "qiankun";
import actions from './actions'
const apps = [
  {
    name: "App1MicroApp",
    entry: '//localhost:9001',
    container: "#app1",
    activeRule: "/app1",
    props: {
      parentActions: actions
    }
  }
];

registerMicroApps(apps);
start();

这样就把这个 actions 传给了子应用。

子应用:

let instance = null
let router = null

function render (props) {
  router = new VueRouter({
    base: window.__POWERED_BY_QIANKUN__ ? '/app1' : '',
    mode: 'history',
    routes: routes
  })
  instance = new Vue({
    router,
    store,
    // 挂载在根节点上
    data(){
      return {
        parentActions: props.parentActions,
      }
    },
    render: (h) => h(App)
  }).$mount('#app')
}

export async function mount(props) {
  render(props);
}

// 在子应用中使用就可以访问到这个parentActions了
this.$root.parentActions.setGlobalState({ num: 2 })
// 调用挂载在 actions 上的自定义方法,获取当前的全局 state
this.$root.parentActions.getGlobalState()

我在子应用的 mounted 中把全局 state 的 num 设置了 2,就是如下效果。
在这里插入图片描述

子传父

上面例子其实已经都包括了。再总结一下就是:

父传子就是父应用通过 props 把 parentActions 传给子应用,子传父就是子应用接受到 parentActions 可以来改变父应用的状态。

5、shared 方案

这个方案我大概描述一下,就不写代码细讲了,因为和上面的方案很像。

就是父应用通过 vuex 或者 redux 正常使用维护一个 state,然后创建一个 shared 实例,这个实例提供对 state 的增删改查,然后通过 props 把这个 shared 实例传给子应用,子应用使用就行。

主应用:
这个 shared 实例大概就长这样:

// micro-app-main/src/shared/index.ts
import store from "./store";

class Shared {
  /**
   * 获取 Token
   */
  public getToken(): string {
    const state = store.getState();
    return state.token || "";
  }

  /**
   * 设置 Token
   */
  public setToken(token: string): void {
    // 将 token 的值记录在 store 中
    store.dispatch({
      type: "SET_TOKEN",
      payload: token
    });
  }
}

const shared = new Shared();
export default shared;

同样的传入方式
src/micro/index.js

import {
  registerMicroApps,
  start,
} from "qiankun";
import shared from './shared'
const apps = [
  {
    name: "App1MicroApp",
    entry: '//localhost:9001',
    container: "#app1",
    activeRule: "/app1",
    props: {
      parentShared: shared
    }
  }
];

registerMicroApps(apps);
start();

想要了解具体可以看这篇文章:
https://cloud.tencent.com/developer/article/1770605

总结

  • 类似设置全局共享 token 就适合方案1
  • 每个页面要设置不同的title,可以用方案2在 url 上带上一个 title,这样父子应用都能监听到
  • 方案3则适合一些复杂一点的数据交互
  • 一般到方案3,就可以了,如果需要方案4了,就说明应用交流太频繁了,考虑是不是你们的应用拆分的有问题

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/58367.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

S/4HANA(本地部署或云版)跟 SAP 家族系统以及非SAP系统的集成,到底什么是推荐的方式?

笔者的知识星球&#xff0c;有朋友提问&#xff1a; S4HANA(本地部署或云版)跟SAP家族系统以及非SAP系统的集成&#xff0c;sap的标准/推荐做法是通过BTP还是直接连接&#xff0c;或者是根据目标系统分别选择&#xff1f;有参考链接最好了。 首先 SAP S/4HANA 的技术栈&#xf…

java数组应用(栈和队列以及酒店模拟)

1.编写程序,使用一维数组,模拟栈数据结构 要求1.栈内可以存放任意数据2.栈内提供push方法模拟压栈3.栈内提供pop方法模拟出栈4.栈的大小默认为10 新建MyStack类 /*** author DeYou* date 2022/11/10 23:01*/ public class MyStack {Object[] element;int index;public MyStack…

blender Eevee渲染器

文章目录简介.采样.环境光遮蔽.辉光.景深.次表面散射.屏幕空间反射.间接光照明.阴影.体积.简介. 1 EV渲染器是实时渲染&#xff0c;类似于游戏引擎,效果差于Cycles 2 EV渲染器使用的设备是显卡 采样. 1 渲染和视图分别指渲染模式和视图模式的采样值&#xff0c;值越大&#…

Android Studio 中MotinLayout的简单使用

​ 一、什么是MotionLayout MotionLayout 是一种布局类型&#xff0c;可帮助您管理应用中的运动和微件动画。MotionLayout 是 ConstraintLayout 的子类&#xff0c;在其丰富的布局功能基础之上构建而成。 二、使用MotionLayout的准备 1.添加MotionLayout依赖项 要在项目中使用…

【菜鸡读论文】Face2Exp: Combating Data Biases for Facial Expression Recognition

【菜鸡读论文】Face2Exp: Combating Data Biases for Facial Expression Recognition 最近上海开始降温了&#xff0c;而且常常下雨&#xff0c;天气开始变得好冷啊&#xff01;以前年轻的时候冬天经常穿的少&#xff0c;现在膝盖开始有点遭不住了&#xff0c;小伙伴们一定要保…

Go字符串拼接6种方式及其性能测试:strings.builder最快

Go字符串拼接常见的方式有加号、fmt.Sprintf、strings.Builder、bytes.Buffer、strings.join、切片。 package concat_stringimport ("bytes""fmt""strconv""strings""testing" )const numbers 100// func BenchmarkStri…

Kafka安装与配置

1、Java环境为前提 &#xff08;1&#xff09;上传jdk-8u261-linux-x64.rpm到服务器并安装&#xff1a; rpm -ivh jdk-8u261-linux-x64.rpm &#xff08;2&#xff09;配置环境变量&#xff1a; vim /etc/profile # 生效 source /etc/profile # 验证 java -version 2、Zook…

贝叶斯定理~~概率分布

还是搬来了基础自己学习用哦 ~~ 从最基础的概率论到各种概率分布全面梳理了基本的概率知识与概念&#xff0c;这些概念可能会帮助我们了解机器学习或开拓视野。这些概念是数据科学的核心&#xff0c;并经常出现在各种各样的话题上。重温基础知识总是有益的&#xff0c;这样我们…

适应性哈夫曼编码(Adaptive Huffman coding)

适应性哈夫曼编码适应性哈夫曼编码简介算法示例适应性哈夫曼编码 简介 适应性哈夫曼编码&#xff08;Adaptive Huffman coding&#xff09;&#xff0c;又称动态哈夫曼编码&#xff08;Dynamic Huffman coding&#xff09;&#xff0c;是基于哈夫曼编码的适自适应编码技术。它…

深度学习Day07

Recurrent Neural Network 智慧客服——Slot Filling 根据上 下文产生不同的output

Java搭建宝塔部署实战毕设项目WMS仓库管理系统源码

大家好啊&#xff0c;我是测评君&#xff0c;欢迎来到web测评。 本期给大家带来一套Java开发的毕业设计项目WMS仓库管理系统源码。 技术架构 技术框架&#xff1a;SpringMVC Mybatis Ehcache bootstrap jquery mysql5.7运行环境&#xff1a;jdk8 nginx1.20 tomcat9 In…

基于PSO粒子群算法的MPPT最大功率跟踪Simulink仿真,PSO采用S函数实现

目录 1.算法描述 2.仿真效果预览 3.MATLAB核心程序 4.完整MATLAB 1.算法描述 MPPT控制器的全称是“最大功率点跟踪”&#xff08;Maximum Power Point Tracking&#xff09;太阳能控制器&#xff0c;是传统太阳能充放电控制器的升级换代产品。MPPT控制器能够实时侦测太阳能…

30岁自学Python转行靠谱吗?

前言 30岁自学Python转行靠谱吗&#xff1f;若啃学习任何时候都不晚&#xff0c;关键是学习完用来做什么。提高工作效率&#xff0c;写些脚本实现自动化办公这些完全没问题。如果学python是为了转开发&#xff0c;建议慎重考虑&#xff0c;程序开发转Python相对容易些&#xf…

[附源码]计算机毕业设计血库管理系统Springboot程序

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

计算机网络——运输层【重点】

运输层概述 概念 进程之间的通信 从通信和信息处理的角度看&#xff0c;运输层向它上面的应用层提供通信服务&#xff0c;它属于面向通信部分的最高层&#xff0c;同时也是用户功能中的最低层。当网络的边缘部分中的两个主机使用网络的核心部分的功能进行端到端的通信时&…

【SpingBoot拦截器】实现两个接口,配置拦截路径

文章目录SpingBoot拦截器拦截器与过滤器的区别&#xff1a;1.HandlerInterceptor接口2.WebMvcConfigurer接口3.示例&#xff1a;SpingBoot拦截器 【SpringWeb框架中的拦截器作用类似于过滤器&#xff0c;都可以对一个请求进行拦截处理。】 我们可以用拦截器做很多事情&#xf…

使用HTML制作静态网站作业——我的校园运动会(HTML+CSS)

&#x1f389;精彩专栏推荐 &#x1f4ad;文末获取联系 ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业&#xff1a; 【&#x1f4da;毕设项目精品实战案例 (10…

Java项目:SSM企业门户网站

作者主页&#xff1a;源码空间站2022 简介&#xff1a;Java领域优质创作者、Java项目、学习资料、技术互助 文末获取源码 项目介绍 本项目分为前后台&#xff0c;前台主要用于官网展示&#xff0c;后台主要为管理员管理&#xff0c; 管理员角色包含以下功能&#xff1a; 管理员…

Rook Ceph浅谈

storageclass是最省心的&#xff0c;上面三种删除了容器存储还在 下图是管理员定义pv&#xff0c;用户不知道这些细节 PersistentVolume pv会跟后端的存储rbd对接 用户通过PVC调用PV ,根据10G容量去pv里找相匹配的自动关联 上图就叫 pvc-demo StorageClass 更厉害 管理员…

PostgreSQL 内核可观测性体系

文章目录背景Metricspgstat指标展示指标统计相关的guc 参数pgstat 实现pg_stat_statements基本用法及指标内容pg_stat_statements 实现Trace总结背景 PG 作为一个演讲30多年历史的TP 数据库&#xff0c;其复杂度极高&#xff0c;如果帮助DBA 在线上分析复杂查询的问题或者构建…