首页IT科技微前端 乾坤源码分析(微前端:qiankun的五种通信方式)

微前端 乾坤源码分析(微前端:qiankun的五种通信方式)

时间2025-04-29 02:30:25分类IT科技浏览3629
导读:背景 今天盘点一下 qiankun 父子应用的通信方式都有哪些,我发现了 5 种。...

背景

今天盘点一下 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了                ,就说明应用交流太频繁了               ,考虑是不是你们的应用拆分的有问题

创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!

展开全文READ MORE
uniapp前端面试题(uniApp常见面试题) zmweb.exe是什么进程(hkwnd.exe是什么进程 作用是什么 hkwnd进程查询)