微前端乾坤(qiankun)的后台标签页功能实现

本文章仅记录我的开发历程,想要干货的请参考我下面的链接,本文可以略过了

react主应用增加tabs标签的逻辑

这里可以参考上面第一个链接,但是由于文章里的页面缓存实现是在父应用里实现的多例子应用,即每个页面都是一个单独的实例,页面多的情况下应该会有性能问题。所以只抄袭借鉴了这个文章里的tabs标签页的操作逻辑,页面缓存功能另寻出路。

子应用增加页面缓存

参考上面第二个链接,实现思路为在子应用unmount时,不调用vue或react的卸载事件,将rootDom append到document.body里面,并用样式隐藏,子应用重新mount时,将隐藏的rootDom显示

vue子应用

入口改造

ts 复制代码
let rootDom: Element | undefined;

async function render(props: any) {
  console.log("render");
  const { container } = props;
  const root = createApp(VueApp);
  root.use(createPinia());
  root.use(router);
  root.provide("appStore", props.appStore);
  rootDom = container ? container.querySelector("#root") : document.getElementById("root");
  root.mount(rootDom!);
}

renderWithQiankun({
  update() {},
  mount(props) {
    console.log("mount", props);
    props?.setLoading(false);
    if (!rootDom) {
      render(props);
    } else {
      rootDom!.setAttribute("display", "block");
      props.container?.parentNode?.appendChild(rootDom!);
    }
  },
  bootstrap() {
    console.log("bootstrap");
  },
  unmount(props) {
    console.log("unmount", props);
    rootDom!.setAttribute("display", "none");
    document.body.appendChild<Element>(rootDom!);
  },
});

keep-alive实现

js 复制代码
//layout.vue 

<template>
  <RouterView v-slot="{ Component }">
    <KeepAlive v-show="canCache">
      <component :is="Component"></component>
    </KeepAlive>
    <component v-if="canCache" :is="Component"></component>
  </RouterView>
</template>

react子应用

入口改造

ts 复制代码
//请参考vue的

由于react没有原生的KeepAlive组件,使用的是react-activation来实现页面缓存功能,如果需要实现类似vue的maxAPI,可以参考这里

ts 复制代码
// layout.tsx
import { KeepAlive, useAliveController } from "react-activation";
const MAX_CACHE = 10;
const keys: Set<string> = new Set();

const LayoutInner = () => {
  const routes = useLocation();
  const controller = useAliveController();

  const pushKeys = (key: string) => {
    const cachePath = keys.has(key);
    if (cachePath) {
      keys.delete(key);
      keys.add(key);
    } else {
      keys.add(key);
      if (keys.size > MAX_CACHE) {
        const deleteKey = keys.values().next().value;
        keys.delete(deleteKey);
        controller.drop(deleteKey);
      }
    }
  };
  const dom = <Outlet />;

  if (canCache)) {
    pushKeys(routes.pathname);
    return (
      <KeepAlive id={routes.pathname} name={routes.pathname}>
        {dom}
      </KeepAlive>
    );
  }
  return dom;
};

遇到的问题

  • vue子应用回退异常:原因是vue-router依赖了history.state,具体的原因请看这里
  • 场景:从子级页面增加一项数据,回到一级页面,由于做了页面缓存,新增的数据并不会出现在页面上,是一个合理的bug。合理的解决方案:参考ProTable - 高级表格 - ProComponents (ant.design)revalidateOnFocus,在窗口聚焦时重新请求接口
  • refreshTab刷新tab:原贴里使用了改变key的方式rerender页面,但是我们由于有页面缓存,页面加载时的接口等不会重新请求,还没有想到一个同时兼容vue和react的方案,暂时使用window.location.reload()代替
  • ......
相关推荐
hua_ban_yu15 小时前
vue3 + ts 制作指令,防止按钮在固定时间内重复点击,不会影响到表单的校验
前端·javascript·vue.js
老神在在00116 小时前
Token身份验证完整流程
java·前端·后端·学习·java-ee
利刃大大16 小时前
【Vue】指令修饰符 && 样式绑定 && 计算属性computed && 侦听器watch
前端·javascript·vue.js·前端框架
徐小夕@趣谈前端17 小时前
NO-CRM 2.0正式上线,Vue3+Echarts+NestJS实现的全栈CRM系统,用AI重新定义和实现客户管理系统
前端·javascript·人工智能·开源·编辑器·echarts
catino17 小时前
图片、文件上传
前端
Mr Xu_18 小时前
Vue3 + Element Plus 实现点击导航平滑滚动到页面指定位置
前端·javascript·vue.js
小王努力学编程18 小时前
LangChain——AI应用开发框架(核心组件1)
linux·服务器·前端·数据库·c++·人工智能·langchain
pas13618 小时前
35-mini-vue 实现组件更新功能
前端·javascript·vue.js
前端达人18 小时前
为什么聪明的工程师都在用TypeScript写AI辅助代码?
前端·javascript·人工智能·typescript·ecmascript
快乐点吧18 小时前
使用 data-属性和 CSS 属性选择器实现状态样式控制
前端·css