一、基于微前端qiankun的多页签缓存方案实践
1、多个子应用同时存在
在dom上通过v-show控制显示哪一个子应用,及display:none;控制不同子应用dom的显示隐藏
1.png
1.png
url变化时,在路由守卫那控制通过loadMicroApp手动控制加载哪个子应用
2.png
缓存的菜单信息放在vuex状态管理里面,实时更新新增和删除菜单
3.png
然后在每个子应用使用keep-alive,通过include缓存页面
3.png
以上多页签缓存就实现了。需要注意的是在系统退出后记得手动调用unmount方法卸载子应用。不然退出登录不刷新直接在登录进来页面会空白
4.png
具体代码如下
1、主应用代码
主应用.vue
<template>
<div>
<div class="main-page-wrapper">
<router-view v-show="widgets[showIndex].type === 'main'" />
<div
v-show="widgets[showIndex].type !== 'main'"
id="sub-project-container"
>
<div
v-for="(app, index) in microApps"
:key="index"
v-show="route.path.startsWith(app.activeRule)"
:id="`appContainer${index + 1}`"
></div>
</div>
</div>
</div>
</template>
<script>
import microApps from '@/micro'
</script>
micro/index.js
const microApps = [
{
name: 'join-ewms-base-module',
entry: process.env.VUE_APP_JOIN_EWMS_BASE_MODULE_PROJECT,
container: '#appContainer1',
activeRule: '/join-ewms-base-module',
props: {
data: 'join-ewms-base-module子应用',
mainAppRouter: router,
mainAppHttp: http,
mainAppStore: store,
mainAppUtils: utils,
mainAppExcel: excel,
mainAppCommonRequestMethod: commonRequestMethod
}
},
{
name: 'join-ewms-ish-module',
entry: process.env.VUE_APP_JOIN_EWMS_ISH_MODULE_PROJECT,
container: '#appContainer2',
activeRule: '/join-ewms-ish-module',
props: {
data: 'join-ewms-ish-module子应用',
mainAppRouter: router,
mainAppHttp: http,
mainAppStore: store,
mainAppUtils: utils,
mainAppExcel: excel,
mainAppCommonRequestMethod: commonRequestMethod
}
}
]
// 子应用
export default microApps
路由
route.js
let activeApps = {}
router.beforeEach(async (to, from, next) => {
const conf = microApps.find(item => to.path.indexOf(item.activeRule) !== -1)
if (to.path === '/login') {
activeApps = {}
// 主应用内跳转
next()
} else {
const refresh = sessionStorage.getItem('afterRefresh')
if (refresh === 'true') {
sessionStorage.setItem('afterRefresh', 'false')
next({ path: '/' })
} else {
// 应用跳转
if (conf) {
const cacheMicro = activeApps[conf.activeRule]
// 已缓存应用
if (cacheMicro) {
next()
return
}
// 未缓存应用
if (conf.activeRule === '/join-ewms-mip-module') {
activeApps[conf.activeRule] = loadMicroApp({ ...conf, router }, { sandbox: { experimentalStyleIsolation: true } })
} else {
activeApps[conf.activeRule] = loadMicroApp({ ...conf, router })
}
next()
} else {
// 主应用内跳转
next()
}
}
}
})
// 卸载子应用方法
export function unmountMicroApps () {
for (const key in activeApps) {
activeApps[key].unmount()
delete activeApps[key]
2、子应用代码
App.vue
<template>
<el-config-provider :locale="locale">
<router-view #default="{Component}">
<keep-alive :include="cacahview">
<component
:is="Component"
:key="route.fullPath"
/>
</keep-alive>
</router-view>
</el-config-provider>
</template>
<script>
import zhCn from 'element-plus/lib/locale/lang/zh-cn'
import { ref } from 'vue'
import { useRoute } from 'vue-router'
import { useStore } from 'vuex'
import actions from '@/shared/actions'
export default {
name: 'AppComponent',
setup () {
const route = useRoute()
const store = useStore()
const cacahview = ref([])
actions.onGlobalStateChange(state => {
const { cachedViews } = state
const data = cachedViews.map(item => {
return {
menu_id: item.menu_id,
cache: item.menu_url.split('/')[2]
}
})
data.shift()
cacahview.value = data.map(item => {
if (item.cache.indexOf('?') !== -1) {
item.cache = item.cache.split('?')[0]
}
if (item.cache === 'OutputTemplate') {
item.cache = `OutputTemplate${item.menu_id}`
}
return item.cache
})
}, true)
return {
locale: zhCn,
route,
cacahview
}
}
}
</script>
<style lang="scss">
</style>
二、如何在主应用刷新具体缓存子页面
实现方式是,点击刷新按钮,跳转到一个过渡页面,然后过渡页面在跳回原来的页面
1.png
过渡页面
2.png