qiankun微应用之间、主微应用之间相互跳转方式总结与实践

一、子应用互相访问

1、背景

(1)未来可能需要做不同子应用菜单的合并,如在bi应用下的侧边栏或者别的地方,需要跳转到数据治理的数仓主题里,或者涉及到子应用值改变,其他应用也需要使用;

(2)a标签跳转会使整个页面重新刷新,原来的状态都会丢失掉;

(3)用子应用router的history跳转会带上子应用的base,导致路由跳转404。这就造成使用微应用 router 的方法无法跳回主应用,也就无法直接跳到其他微应用。

2、解决方法

(1) 通过history.pushState()方式跳转。 //不刷新页面,更改页面的url

  • state:一个与指定网址相关的状态对象,popstate事件触发时,该对象会传入回调函数。如果不需要这个对象,此处可以填null。
  • title:新页面的标题,但是所有浏览器目前都忽略这个值,因此这里可以填null。
  • url:新的网址,必须与当前页面处在同一个域。浏览器的地址栏将显示这个网址。

注意:该方式使用的前提是路由系统底层用的是 history 模式。

示例如下:

  • 在该A子应用下,定义侧边栏时,自定义跳转到B应用的菜单栏,应用isAnotherProject加以标识;定义字段记录子应用的对应path记录。

  • 在点击侧边栏跳转时,做出相应判断后,通过window.history.pushState(null,'',path)跳转。

(2) 将主应用的路由实例传递给子应用,子应用使用主应用的路由实例进行跳转。

API——>registerMicroApps(apps, lifeCycles) 注册微应用配置信息。

  • apps - Array<RegistrableApp> - 必选,微应用的一些注册信息
  • lifeCycles - LifeCycles - 可选,全局的微应用生命周期钩子

示例如下:

  • 在主应用中的registerAppConfig文件中注册微应用配置信息,在有微应用间相互跳转的相关配置信息里,将路由实例传递通过props传递进去。

  • 在子应用的main.js的mount函数里将接收到的 props 参数内的函数挂在 vue 原型上方便使用,你也可以在其他导出的生命周期函数内得到 props 并按照你的设想去处理。

  • 挂载成功后,可以在该子应用内的需要进行跨子应用跳转时使用父组件的router实例,直接进行相应的跳转、路由传参。

二、子应用到主应用

1. 解决方法

(1) 通过history.pushState()方式跳转。

(2) 通过主应用路由实例跳转,实践发现会出现主应用css未加载的情况。

现象:

从子项目页面跳转到主项目自身的页面时,主项目页面的 css 未加载的 bug。

原因:

在子项目跳转到父项目时,子项目的卸载需要一点点的时间,在这段时间内,父项目加载了,插入了 css,但是被子项目的 css 沙箱记录了,然后被移除了。父项目的事件监听也是一样的,所以需要在子项目卸载完成之后再跳转。本来考虑在路由钩子函数里面判断下,子项目是否卸载完成,卸载完成再跳转路由,然而路由不跳转,子项目根本不会卸载。

解决办法:

先复制一下 HTMLHeadElement.prototype.appendChild 和 window.addEventListener ,路由钩子函数 beforeEach 中判断一下,如果当前路由是子项目,并且去的路由是父项目的,则还原这两个对象。

const parentRoute = ['/home']; //主应用路由
const isParentRoute = (path: string) => parentRoute.some(item => path.startsWith(item));
const rawAppendChild = HTMLHeadElement.prototype.appendChild;
const rawAddEventListener = window.addEventListener;
router.beforeEach((to, from, next) => {
    // 从子项目跳转到主项目
    //如果当前路由是子项目,并且去的路由是父项目的,则还原这两个对象
    if (!isParentRoute(from.path) && isParentRoute(to.path)) {
        HTMLHeadElement.prototype.appendChild = rawAppendChild;
        window.addEventListener = rawAddEventListener;
    }
    console.log(isParentRoute(from.path), isParentRoute(to.path), !isParentRoute(from.path) && isParentRoute(to.path));

这样就可以正常在微应用里通过父应用的路由实例进行跳转了。

const parentRoute = ['/home']; //主应用路由
const isParentRoute = (path: string) => parentRoute.some(item => path.startsWith(item));
const rawAppendChild = HTMLHeadElement.prototype.appendChild;
const rawAddEventListener = window.addEventListener;
router.beforeEach((to, from, next) => {
    // 从子项目跳转到主项目
    //如果当前路由是子项目,并且去的路由是父项目的,则还原这两个对象
    if (!isParentRoute(from.path) && isParentRoute(to.path)) {
        HTMLHeadElement.prototype.appendChild = rawAppendChild;
        window.addEventListener = rawAddEventListener;
    }
    console.log(isParentRoute(from.path), isParentRoute(to.path), !isParentRoute(from.path) && isParentRoute(to.path));

三、以上两种方案比较(加之前使用的url跳转方式)

window.history.pushState

将主应用路由实例注入子应用

使用 window.location.href 等方法进行 url 跳转跳转

速率

页面切换速率明显加快

页面切换速率明显加快

页面首次加载渲染时间很长

页面效果

无白屏情况出现

无白屏情况

首次加载,会出现一段时间的白屏,体验不佳

实现复杂程度

轻量级

实现较为复杂(考虑子应用跳转主应用会出现主应用样式未加载的bug,需要额外添加代码处理该情况)

-------------------------

利弊

  • 要求各个应用路由系统都使用history模式;
  • 切换时,仅改变url,不会导致页面刷新。
  • 正式方案,衔接各个应用自然;
  • 会出现主项目页面的 css 未加载的 bug。
  • 出现白屏;
  • 首次加载缓慢。

四、总结

结合项目现状,实现复杂程度,考虑使用window.history.pushState该方式跳转更加合理便捷。

???随记:
调主应用的路由,主应用再去匹配分发到子应用路由
跳转的时候先判断是否在qiankun环境下,如果是qiankun环境下,调用h5自带的history.pushState()跳转
如果是子应用独立开发部署,就使用路由跳转。
import { history as umiHistory } from 'umi';

export const qiankunJump = (url:string, name="页面名称",params=null) => {
window.POWERED_BY_QIANKUN ? history.pushState(params, name, url) : umiHistory.push(url);
}

qiankunJump('/routePath')

五、如果我的路由模式是hash,子应用之间该如何跳转?

对于使用hash模式的路由,在子应用程序之间进行跳转时,可以使用`window.location.hash`属性来修改URL的hash部分,从而实现跳转。这种方式可以避免页面的白屏问题。

以下是一个示例,展示了如何在子应用程序中使用hash模式进行跳转:

// 在子应用程序中进行hash路由跳转
window.location.hash = '#目标路由';

通过修改`window.location.hash`属性,您可以在当前子应用程序中进行hash路由的跳转。

请注意,当您在子应用程序之间进行hash路由跳转时,qiankun会自动感知到URL的变化,并加载相应的子应用程序。这样可以保持应用程序的微前端特性,并且不会导致页面的白屏。

  • 9
    点赞
  • 44
    收藏
    觉得还不错? 一键收藏
  • 17
    评论
Qiankun 应用框架是一个基于前端架构的框架,它可以帮助开发者构建多个独立的应用,并能够将这些应用整合到一个主应用中。下面是 Qiankun 应用框架的简要介绍: 1. **前端架构**:Qiankun 应用框架采用前端架构,将主应用应用分开部署,每个应用都有自己的独立代码库和运行环境。 2. **部署方式**:Qiankun 应用框架的部署方式是将每个应用分别编译好,然后将主应用应用部署到 Nginx 配置好的目录中。 3. **代码库管理**:开发者可以分别进入 portal、app1、app2 等目录,执行相关命令来编译、打包、启动等操作。 4. **主应用引入应用**:主应用可以通过引入 Qiankun 注册的应用,并编写导航页显示跳转逻辑,来实现应用的集成。 5. **跨域问题解决**:Qiankun 应用框架支持跨域配置,开发者可以在 Nginx 配置中设置相应的跨域规则,以解决跨域问题。 6. **JS变量隔离**:Qiankun 应用框架支持使用 JS Sandbox 技术来实现变量隔离。每个应用都有自己的沙箱环境,可以避免不同应用之间的变量冲突。 7. **应用生命周期管理**:Qiankun 应用框架支持每个应用的生命周期管理,可以根据需要定制应用的启动、停止等操作。 总的来说,Qiankun 应用框架提供了一种简单、灵活的方式来构建多个独立的应用,并将其整合到一个主应用中。它可以帮助开发者更好地管理代码库、解决跨域问题、实现变量隔离等,从而提高开发效率和软件质量。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 17
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值