一、子应用互相访问

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')

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

  1. 微服务架构与Docker容器之间关系

    微服务j架构与Docker容器之间关系 因公司业务市场的发展与技术架构等结合因素,希望接下来的产品架构能支撑轻量级.高并发.大数据.智能化.易维护.动态扩展等方向发展,因项目性能问题需要处理,公司架构 ...

  2. Spring Cloud【Finchley】实战-03订单微服务与商品微服务之间的调用

    文章目录 Spring Cloud[Finchley]专栏 概述 HTTP方式之RestTemplate 方式一 (直接使用restTemplate访问URL,url写死) 方式二 (使用LoadBa ...

  3. qiankun 传统项目配置_微前端 qiankun 项目实践

    原标题:微前端 qiankun 项目实践 作者:zxh1307 https://juejin.im/post/5ea55417e51d4546e347fda9 导语 最近在做微前端的项目 , 过程中真 ...

  4. 额外域控与主域控之间的数据同步

    额外域控与主域控之间数据同步 一.准备 在虚拟机上准备三台Windows Server 2008,一台作为主域控,一台作为额外域控,一台作为客户端. 主域控 的IP地址为172.18.11.1 额外域 ...

  5. 出行神器“微图APP”主界面功能概述

    微图的主界面主要包括主菜单功能.搜索定位功能.用户登录.栅格地图切换.矢量图层管理.快速标注.打开3D在线地球.视图显示控制.工具箱.定位到当前位置.视图缩放功能.开启GPS导航.照片拍摄.编辑绘制和 ...

  6. 【微前端】1404- 常用微前端架构的几种技术选型

    原文: https://juejin.cn/post/7113503219904430111?share_token=a2d6b49c-d8ce-4448-acd3-d71bbc6e228d 作者:小 ...

  7. Spring Cloud【Finchley】实战-04将订单微服务与商品微服务分别拆分为多模块

    文章目录 Spring Cloud[Finchley]专栏 概述 Product微服务功能分析及多模块拆分 拆分原则 Step1. 调整主(父)工程的工程类型 packaging为pom Step2. ...

  8. 【微前端架构】微前端——功能团队中缺失的一块拼图

    在任何合法的前端开发团队中,提高可扩展性和敏捷性很少会成为头等大事.在处理大型.复杂的产品时,如何确保快速.频繁地交付同时包含后端和前端的功能?像后端那样将前端单体分解成许多更小的部分似乎是答案.如果 ...

  9. 创意Game可用性微交互设计—视觉空间微交互设计

    微交互'细节'表现(有滋有味去品尝) 继上篇<创意Game交互可用性设计>我们从区间操作出发.述写Game UI与交互息息相关的故事.以此方向不断深入研究结果让我欣喜若狂. 现在我们再述那 ...

最新文章

  1. 别让自己变为一个废掉的程序猿
  2. Nginx相关基础配置详解
  3. 微软宣布Azure Function支持Python
  4. Spring AOP(一) AOP基本概念
  5. Packstack安装havana后,计算节点连接DB错误解决
  6. 网页小菜单动画 网格分类菜单特效源码
  7. 【CVPR2019】Workshops 研讨会列表及链接
  8. 机器学习——人工神经网络(NN)
  9. 程序猿必看的10部黑客电影
  10. Chrome 浏览器翻译停服!改Hosts也失效!还有这些解决方案
  11. 企业应该怎样选择mes系统?
  12. 载入模型部分权重的方法
  13. 数商云:分享国内快消品B2B平台的仓储物流模式
  14. ubuntu18.04鼠标正常使用,而键盘失灵
  15. 行业调研:Platform Ops
  16. 如何打印pmd和*pmd的值
  17. 机器学习及Matlab实现-从基础到实战
  18. 集合框架——Set集合的使用与数据结构详解
  19. GsyVideoPlayer视频分析使用
  20. 小米扫地机器人粉尘盒_【小米 米家 扫地机器人开箱展示】开关|上盖|集尘盒_摘要频道_什么值得买...

热门文章

  1. V神是谁?他是以太坊创始人,是区块链界的真正大佬
  2. digg bt_Real Web 2.0,见识digg.com和Reddit,Slashdot的继承人
  3. 说英语的思路(狂飙版)
  4. 初学者如何学习单片机
  5. uniapp唤起谷歌地图APP
  6. iris文件服务器,iris 网络
  7. 中国第三方输入法行业发展趋势如何?看这篇报告就够了
  8. web安全|渗透测试|网络安全11天
  9. Logic Pro 使用教程之 Quick Sampler(非常详细)
  10. 名称:53KF网站客服系统 v3.0.1官方版