【前端】VUE 缓存动态页面 JeecgBoot切换tab缓存全部标签页
src/layouts/page/index.vue
<template>
<!-- 模板保持不变 -->
<RouterView>
<template #default="{ Component, route }">
<keep-alive v-if="openCache" :include="cachedNames">
<component :is="Component" :key="routeKey(route, Component)" />
</keep-alive>
<component v-else :is="Component" :key="routeKey(route, Component)" />
</template>
</RouterView>
<FrameLayout v-if="getCanEmbedIFramePage" />
</template>
<script lang="ts">
import { computed, defineComponent, ref, watch } from 'vue';
import FrameLayout from '/@/layouts/iframe/index.vue';
import { useRootSetting } from '/@/hooks/setting/useRootSetting';
import { useTransitionSetting } from '/@/hooks/setting/useTransitionSetting';
import { useMultipleTabSetting } from '/@/hooks/setting/useMultipleTabSetting';
import { useMultipleTabStore } from '/@/store/modules/multipleTab';
import { useRoute, RouteLocationNormalized } from 'vue-router';
export default defineComponent({
name: 'PageLayout',
components: { FrameLayout },
setup() {
const { getShowMultipleTab } = useMultipleTabSetting();
const tabStore = useMultipleTabStore();
const { getOpenKeepAlive, getCanEmbedIFramePage } = useRootSetting();
const { getBasicTransition, getEnableTransition } = useTransitionSetting();
const openCache = computed(() => getOpenKeepAlive.value && getShowMultipleTab.value);
const cachedNames = ref<string[]>([]);
const route = useRoute();
// 存储路由路径与组件名称的映射
const routeComponentMap = new Map<string, string>();
// 存储当前标签页数量
const lastTabCount = ref(0);
/**
* 自动收集所有访问过的组件名称
*/
watch(
() => route.fullPath,
() => {
const comp = route.matched?.slice(-1)[0]?.components?.default;
if (!comp) return;
// 取组件的 name
let compName = comp.name;
// 如果组件没有 name,就动态生成一个唯一的
if (!compName) {
compName = `Route_${route.name || route.path.replace(/\//g, '_')}`;
comp.name = compName; // 挂到组件实例上
}
// 存储路由与组件名称的映射
routeComponentMap.set(route.fullPath, compName);
// 加入缓存列表
if (!cachedNames.value.includes(compName)) {
cachedNames.value.push(compName);
}
// 更新标签页数量
lastTabCount.value = tabStore.getTabList.length;
},
{ immediate: true }
);
// 监听标签页数量变化
watch(
() => tabStore.getTabList.length,
(newCount) => {
// 如果标签页数量减少,说明有标签页被关闭
if (newCount < lastTabCount.value) {
// 获取当前所有标签页的路径
const currentTabPaths = new Set(tabStore.getTabList.map(tab => tab.fullPath));
// 检查所有已缓存的路径,删除不在当前标签页中的缓存
routeComponentMap.forEach((compName, path) => {
if (!currentTabPaths.has(path)) {
const index = cachedNames.value.indexOf(compName);
if (index !== -1) {
cachedNames.value.splice(index, 1);
}
routeComponentMap.delete(path);
}
});
}
// 更新标签页数量
lastTabCount.value = newCount;
}
);
// 保证同一组件不同参数也能缓存
const routeKey = (route: RouteLocationNormalized, Component: any) => {
return `${Component?.name || route.name || route.fullPath}_${route.fullPath}`;
};
return {
getBasicTransition,
getEnableTransition,
openCache,
cachedNames,
getCanEmbedIFramePage,
routeKey,
};
},
});
</script>
1598

被折叠的 条评论
为什么被折叠?



