微前端乾坤(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()代替
  • ......
相关推荐
FlyWIHTSKY几秒前
Vue 3 单文件组件加载顺序详解
前端·javascript·vue.js
霪霖笙箫7 分钟前
真授之以渔:我是怎么从"想给文章配几张图",一步步做出一个可发布 skill 的
前端·人工智能·开源
yzin10 分钟前
【源码】【react】useCallback、useMemo、memo 原理
前端·react.js
CHU72903510 分钟前
扭蛋机盲盒小程序前端功能设计及核心玩法介绍
前端·小程序
毛骗导演13 分钟前
OpenClaw Gateway RPC 运行时:一个 WebSocket 协议引擎的深度解剖
前端·架构
码路飞14 分钟前
不会 Rust 也能玩 WebAssembly:3 个 npm install 就能用的 WASM 神器
前端·javascript·webassembly
sudo_jin15 分钟前
从“输入网址”到“帧级控制”:我对事件循环与主线程管理的终极认知
前端·javascript
flyfox16 分钟前
Kiro AI IDE 深度使用指南:从入门到高效开发
前端·人工智能·ai编程
lovingsoft17 分钟前
Cursor Skills 实战教程:解锁AI编码效率,附多场景案例
前端·人工智能
小凡同志21 分钟前
React vs Vue:两种前端架构哲学的深度解析
前端·vue.js