如何在 qiankun 中使用 Vue3.0 的 keep-alive 功能来维持组件状态?
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>