vue页面和 iframe多页面无刷新方案和并行 并接入 micro 微前端部分思路
前:
新进了一家公司,公司是做电商平台的, 用的系统竟然还是jsp的网站,每次修改页面还需要我下载idea代码,作为一个前端, 这可不能忍,于是向上申请,意思你们后台做的太辣鸡,我要重做,经领导层商议从去年6月开始到今年12月把系统给重构了
公司系统采用的是每个jsp页面都是一个iframe嵌套进去,大概一共有800多个页面, 打开一个页面就是打开一个新iframe,删掉一个页面就是删掉一个iframe,但公司系统逐渐增多,各种erp,供应商,认证系统,数据平台,所以采用了 micro微前端框架 来进行改造
目的
1. 点击每个tab跳转到对应的微前端架构上
2. iframe接入路由体系,刷新自动跳到对应的iframe页面 (以前的老后台没有路由,刷新就是重置)
3. 点击tag刷新,刷新iframe的页面,和对应微应用的刷新
4. 建立公司npm库,把axios进行统一化管理,每个系统避免引入不同的axios
这是菜单重构的主要思路,剩下应该都是业务逻辑上的东西,不做阐述
框架
主应用 main
认证应用user
登录应用login
列述主要逻辑代码,npm库和iframe逻辑可以参考前几篇文章,micro接入参考mirco的文档,微前端较为简单,源码 https://github.com/jd-opensource/micro-app/
<template>
<!-- isBack 是否是老后台, iframeToggle放着iframe的代码具体参考我前几篇文档-->
<div v-show="isBack">
<iframeToggle :routes="routes" ref="iframeRef" />
</div>
<div class="router-container">
<RouterView id="router-container" v-slot="{ Component }">
<keep-alive :include="['g-home', 'menus', 'main-base']">
<component :is="Component" :key="routes.name" />
</keep-alive>
</RouterView>
</div>
</template>
<script>
const pushState = async (item: TagItem) => {
document.title = item.meta.menuName;
const { appName } = item.meta;
const { path, hash } = item;
activeName.value = item.path;
loading.value = true;
isBack.value = appName === "g-back";
// 如果是back
if (!getActiveApps().includes(appName)) {
// openBackTags(item);
// child-vite 和 child-react17子应用为hash路由,这里拼接一下hash值
hash && `${path}/${hash}`;
// 主应用跳转
router.push(path);
} else {
let childPath = null;
// child-vite 和 child-react17子应用是hash路由,hash值就是它的页面地址,这里单独处理
if (hash) {
childPath = hash;
} else {
// path的值形式如:/app-vue2/page2,这里/app-vue2是子应用的基础路由,/page2才是页面地址,所以我们需要将/app-vue2部分删除
childPath = path.replace(/^\/g-[^/]+/, "");
!childPath && (childPath = "/"); // 防止地址为空
}
if (currentAppName.value !== appName) {
router.push(path);
}
microApp.setData(appName, {
current: { ...item, path: childPath },
type: "navigate",
key: new Date().getTime(),
});
router.replace(`/${appName}${childPath}`);
}
currentAppName.value = appName;
loading.value = false;
};
// 刷新逻辑 采用eventbus方案,告诉对应的iframe+id 页面,进行刷新 document.getElementById(`iframe${id}`).src = path || document.getElementById(`iframe${id}`).src;
/子应用也采用eventbus方案,微前端通知子应用,告诉子应用对应的路由名称,通知vue路由进行页面刷新
const refreshLink = async (item: TagItem) => {
if (item.path.includes("/g-back/iframe")) {
nextTick(() => {
eventBus.emit('refreshIframe', { path: item.meta.link, id: item.meta.id });
});
} else if (item.path === "/home") {
eventBus.emit(item.path);
} else {
microApp.setData(item.meta.appName, {
current: item,
type: "refresh",
key: new Date().getTime(),
});
}
};
</script>
目前公司已经无缝替换以前的老后台系统了,还算是成功,代码用了很多cursor替我补写了很多ts代码,很好用