欢迎您访问 最编程 本站为您分享编程语言代码,编程技术文章!
您现在的位置是: 首页

如何在 qiankun 中使用 Vue3.0 的 keep-alive 功能来维持组件状态?

最编程 2024-08-02 19:32:10
...

qiankun vue3.0 保持组件状态 keep-alive 的使用

      • 方案一
        • 实现思路:
        • 方案优势:
        • 方案不足:
      • 方案二:
        • 实现思路:
        • 方案优势:
        • 方案不足:
      • 由于时间紧张所以采用了方案二,具体入下
      • 一 路由改造
      • 二 keep-alive修改

前段时间在做项目迁移,原来项目架构用的Vue3+TS+Vite,迁移到qiankun项目中,一切都算顺利,但是再后面考虑到因为是后端数据管理平台,所以用户可能同时打开多个标签进行对比数据,会涉及到缓存问题,经过一番折腾终于搞定了现在做下总结

方案一

同一时间仅加载一个子应用,同时保存其他应用的状态

实现思路:

1.通过registerMicroApps注册子应用,qiankun会通过自动加载匹配的子应用。

2.参考keep-alive实现方式,每个子应用都缓存自己实例的vnode,下次进入子应用时可以直接使用缓存的vnode直接渲染为真实DOM。

方案优势:

1.同一时间,只是展示一个子应用的active页面,可减少DOM节点数。

2.非active子应用卸载时同时会卸载DOM及不需要的事件监听,可释放一定内存。

方案不足:

1.没有现有的API可以快速实现,需要自己管理子应用缓存,实现较为复杂。

2.DOM渲染多了一个从虚拟DOM转化为真实DOM的一个过程,渲染时间会比第一种方案稍多。

方案二:

多个子应用同时存在

实现思路:

1.在dom上通过v-show控制显示哪一个子应用,及display:none;控制不同子应用dom的显示隐藏。

2.url变化时,通过loadMicroApp手动控制加载哪个子应用,在页签关闭时,手动调用unmount方法卸载子应用。

方案优势:

1.loadMicroApp是qiankun提供的API,可以方便快速接入。

2.该方式不卸载子应用,页签切换速度比较快。

方案不足:

1.子应用切换时不销毁DOM,会导致DOM节点和事件监听过多,严重时会造成页面卡顿。

2.子应用切换时未卸载,路由事件监听也未卸载,需要对路由变化的监听做特殊的处理。

由于时间紧张所以采用了方案二,具体入下

一 路由改造

主应用路由

// 子应用配置 micro-app.js
export const microApps = [
    {
        name: 'app1',
        entry: import.meta.env.MODE === 'development' ? 'http://localhost:8000/' : `/app1/`,
        container: '#subApp1',
        activeRule: `#/app1`,
        props: {
            action,
            shareMainComponent: { ...shareComponent }
        }
    },
    {
        name: 'app2',
        entry: import.meta.env.MODE === 'development' ? 'http://localhost:9000/' : `/app2/`,
        container: '#subApp2',
        activeRule: `#/app2`,
        props: {
            action,
            shareMainComponent: { ...shareComponent }
        }
    }
]

// 主应用router.js 手动挂载子应用
import {loadMicroApp} from 'qiankun';
// 缓存应用实例
const microList = new Map([])
// 当前应用配置
let current
const routes = [
  {
    path: '/',
    ...
  },
  {
    ...
  }
]

const router = new VueRouter({
  routes
})

router.beforeEach( async (to, from, next) =>{
  const conf = microApps.find(item => to.path.indexOf(item.name) !== -1)
  // 子应用跳转
  if(conf){
    // 未切换子应用
    if(current &&  current.activeRule === conf.activeRule ){
      next()
      return 
    }
    const cacheMicro = microList.get(conf.activeRule)   
    // 已緩存應用
    if(cacheMicro){
      next()
      return
    }
    // 为缓存子应用
    const micro = loadMicroApp({...conf, router}) 
    microList.set(conf.activeRule, micro)
    current = conf
    next()
  }
  // 主应用内跳转
  next()
})

二 keep-alive修改

由于须要缓存子应用,因此咱们须要为每一个子应用配置keep-alive。这里须要注意的地方是,须要将keep-alive配置在子应用的APP.vue根路由下。

这里的子应用都配置在主应用的二,三级路由下,构造出的结构相似多级嵌套的父子路由关系。

因此这里子应用的APP.vue内的渲染入口变成了主应用的嵌套子路径

Vue3.0 使用方式

//子应用需要再APP.vue下
<router-view v-slot="{ Component }">
   <keep-alive>
      <component :is="Component" />
   </keep-alive>
</router-view>

Vue2.0 使用方式

<keep-alive>
  <router-view/>
</keep-alive>