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,需要额外添加代码处理该情况) |
------------------------- |
利弊 |
|
|
|
四、总结
结合项目现状,实现复杂程度,考虑使用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微应用之间、主微应用之间相互跳转方式总结与实践相关推荐
- 微服务架构与Docker容器之间关系
微服务j架构与Docker容器之间关系 因公司业务市场的发展与技术架构等结合因素,希望接下来的产品架构能支撑轻量级.高并发.大数据.智能化.易维护.动态扩展等方向发展,因项目性能问题需要处理,公司架构 ...
- Spring Cloud【Finchley】实战-03订单微服务与商品微服务之间的调用
文章目录 Spring Cloud[Finchley]专栏 概述 HTTP方式之RestTemplate 方式一 (直接使用restTemplate访问URL,url写死) 方式二 (使用LoadBa ...
- qiankun 传统项目配置_微前端 qiankun 项目实践
原标题:微前端 qiankun 项目实践 作者:zxh1307 https://juejin.im/post/5ea55417e51d4546e347fda9 导语 最近在做微前端的项目 , 过程中真 ...
- 额外域控与主域控之间的数据同步
额外域控与主域控之间数据同步 一.准备 在虚拟机上准备三台Windows Server 2008,一台作为主域控,一台作为额外域控,一台作为客户端. 主域控 的IP地址为172.18.11.1 额外域 ...
- 出行神器“微图APP”主界面功能概述
微图的主界面主要包括主菜单功能.搜索定位功能.用户登录.栅格地图切换.矢量图层管理.快速标注.打开3D在线地球.视图显示控制.工具箱.定位到当前位置.视图缩放功能.开启GPS导航.照片拍摄.编辑绘制和 ...
- 【微前端】1404- 常用微前端架构的几种技术选型
原文: https://juejin.cn/post/7113503219904430111?share_token=a2d6b49c-d8ce-4448-acd3-d71bbc6e228d 作者:小 ...
- Spring Cloud【Finchley】实战-04将订单微服务与商品微服务分别拆分为多模块
文章目录 Spring Cloud[Finchley]专栏 概述 Product微服务功能分析及多模块拆分 拆分原则 Step1. 调整主(父)工程的工程类型 packaging为pom Step2. ...
- 【微前端架构】微前端——功能团队中缺失的一块拼图
在任何合法的前端开发团队中,提高可扩展性和敏捷性很少会成为头等大事.在处理大型.复杂的产品时,如何确保快速.频繁地交付同时包含后端和前端的功能?像后端那样将前端单体分解成许多更小的部分似乎是答案.如果 ...
- 创意Game可用性微交互设计—视觉空间微交互设计
微交互'细节'表现(有滋有味去品尝) 继上篇<创意Game交互可用性设计>我们从区间操作出发.述写Game UI与交互息息相关的故事.以此方向不断深入研究结果让我欣喜若狂. 现在我们再述那 ...
最新文章
- 别让自己变为一个废掉的程序猿
- Nginx相关基础配置详解
- 微软宣布Azure Function支持Python
- Spring AOP(一) AOP基本概念
- Packstack安装havana后,计算节点连接DB错误解决
- 网页小菜单动画 网格分类菜单特效源码
- 【CVPR2019】Workshops 研讨会列表及链接
- 机器学习——人工神经网络(NN)
- 程序猿必看的10部黑客电影
- Chrome 浏览器翻译停服!改Hosts也失效!还有这些解决方案
- 企业应该怎样选择mes系统?
- 载入模型部分权重的方法
- 数商云:分享国内快消品B2B平台的仓储物流模式
- ubuntu18.04鼠标正常使用,而键盘失灵
- 行业调研:Platform Ops
- 如何打印pmd和*pmd的值
- 机器学习及Matlab实现-从基础到实战
- 集合框架——Set集合的使用与数据结构详解
- GsyVideoPlayer视频分析使用
- 小米扫地机器人粉尘盒_【小米 米家 扫地机器人开箱展示】开关|上盖|集尘盒_摘要频道_什么值得买...