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

这篇具有很好参考价值的文章主要介绍了微前端:qiankun的五种通信方式。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

背景

今天盘点一下 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 通信的。
qiankun通信,# 微前端,前端,javascript,html5

子传父

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

2、通过路由参数共享

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

父传子

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

子传父

主应用跳到子应用,子应用内部路由跳转携带参数,父应用通过路由守卫可以拿到路由上的参数。
qiankun通信,# 微前端,前端,javascript,html5

从 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,就是如下效果。
qiankun通信,# 微前端,前端,javascript,html5

子传父

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

父传子就是父应用通过 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文章来源地址https://www.toymoban.com/news/detail-842154.html

总结

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

到了这里,关于微前端:qiankun的五种通信方式的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 2023/4/4 常见的五种网络通信协议

    目录 一、Http协议 二、Https协议 三、Socket协议 四、WebSocket协议 五、WebService协议 六、总结 HTTP协议是一种应用层协议,它是基于TCP/IP协议的,主要用于Web应用程序中的客户端与服务器之间的通信,它使用的是请求-响应模式。HTTP协议不支持实时通信和服务器主动推送数据。

    2024年02月09日
    浏览(40)
  • List集合的五种遍历方式

    目录 一、List五种遍历方式  1、普通for遍历 2、 增强for遍历  3、Lambda表达式  4、迭代器遍历  5、列表迭代器 方法 说明 迭代器遍历 在遍历的过程中需要删除元素,请使用迭代器。 列表迭代器 在遍历的过程中需要添加元素,请使用列表迭代器。 增强for遍历 仅仅想遍历,那

    2024年02月10日
    浏览(43)
  • Java遍历Map的五种方式

    java中遍历map一般有五种方法,从最早的Iterator,到java5支持的foreach,再到java8的Lambda表达式。 如果只是获取key,或者value,推荐使用keySet或者values方式 如果同时需要key或者value推荐使用entrySet 如果需要在遍历过程中删除元素推荐使用Iterator 如果需要在遍历过程中增加元素,可

    2024年02月03日
    浏览(53)
  • springboot实现跨域的五种方式

    出于浏览器的同源策略限制。同源策略(Sameoriginpolicy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。可以说Web是构建在同源策略基础之上的,浏览器只是针对同源策略的一种实现。 同源策略 同源策略会

    2024年02月05日
    浏览(50)
  • 微信小程序传参的五种方式

    大家好,今天和大家分享一下微信小程序页面之间传参的五种方式,这个的话也是有人问了我一嘴,然后现在我和大家分享一下。 使用GPT搜索的话给我的答案是纯文字的描述,但是大致就是这样: URL参数传递:可以将参数直接拼接在页面的URL中,在打开目标页面时,通过获

    2024年02月06日
    浏览(38)
  • Vue路由跳转的五种方式

    路由跳转有两种形式:声明式导航、编程式导航 1. router-link 声明式 prop= :to=“…” 相当与 router.push(…) router-link中链接如果是’ / \\\'开始,就是从根路由开始 如果开始不带 ’ / \\\',则是从当前路由开始 例子 2. this.$router.push() 可追溯 编程式 router.push(…)//该方法的参数可以是一个

    2024年02月05日
    浏览(36)
  • Java调用python代码的五种方式

    你还在纠结怎么样在Java中调用python吗?我们在实际工程项目问题中,经常会碰到不同语言代码之间互调的问题,比如此处的Java调用python(常见Java调用python写的处理模型来完成数据处理等)。 让我们来看看具体怎么操作吧! 说明: Java调用不带参数的python代码执行 样例代码

    2024年02月09日
    浏览(46)
  • javaee spring aop 的五种通知方式

    2024年02月10日
    浏览(40)
  • 【SpringBoot】 启动后执行方法的五种方式

    在 SpringBoot 工程 启动后, 执行方法的五种方式: 1、实现 CommandLineRunner 接口 项目初始化完毕后,才会调用方法,提供服务 2、实现 ApplicationRunner 接口 同 CommandLineRunner。只是传参格式不一样。CommandLineRunner:没有任何限制;ApplicationRunner:key-value 3、实现 ApplicationListener 接口

    2023年04月08日
    浏览(43)
  • 将Bean注入Spring容器的五种方式

    将bean放入Spring容器中有哪些方式? 我们知道平时在开发中使用Spring的时候,都是将对象交由Spring去管理,那么将一个对象加入到Spring容器中,有哪些方式呢,下面我就来总结一下 这种方式其实也是我们最常用的一种方式,@Configuration用来声明一个配置类,然后使用 @Bean 注解

    2024年02月05日
    浏览(32)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包