vue项目中,列表进入详情返回列表需要缓存;但是点击菜单又不需要缓存,所以需要结合keep-alive设置页面动态缓存
<template>
<router-view v-slot="{ Component }">
<keep-alive :include="cachedPages">
<component :is="Component" />
</keep-alive>
</router-view>
</template>
<script lang="ts">
import { computed, watch } from 'vue'
import { useStore } from 'vuex'
export default {
setup() {
let store = useStore()
let cachedPages = computed(() => store.state.cachedPages)
// watch(cachedPages, (newVal) => {
// console.log('[cache] keepAlive: ', newVal)
// })
return {
cachedPages,
}
},
}
</script>
import { createStore } from 'vuex'
export default createStore({
state() {
return {
cachedPages: [], // keepAlive 页面
}
},
mutations: {
setCachedPages(state, pages) {
state.cachedPages = pages
},
},
})
import { RouteLocationNormalized } from 'vue-router'
import store from '@/store'
export default function cachePage(route: RouteLocationNormalized) {
//设置的页面缓存类型
const cache = route.meta.cache
//判断页面需不需要缓存
if (cache) {
const matched = route.matched
//当前页面的组件名称
const page = matched[matched.length - 1].components.default.name
// console.log('[cache] current page: ', page)
if (page) {
let pages = [...store.state.cachedPages]
// cache =pre 前置页面,类似于主菜单的页面,进入这个页面时,清空之前的缓存记录,然后保存当前打开的页面
if (cache === 'pre') {
// 前置页面
pages = [page]
} else {
//非前置页面,直接根据,先判断页面之前有没有缓存过(主应用中页面多次跳转同一路由),有先删除,再缓存
const index = pages.indexOf(page)
if (index > -1) {
pages = pages.slice(0, index)
}
pages.push(page)
}
// console.log('[cache] next pages: ', ...pages)
store.commit('setCachedPages', pages)
}
}
}
const routes=[
{
path: 'componentList',
name: 'componentList',
component: componentList,
meta: {
auth: ['prvView'],
cache: 'pre',
},
},
// 构件包
{
path: 'package',
redirect: {
name: 'packageList',
},
},
{
path: 'package/index',
name: 'packageList',
component: packageList,
meta: {
auth: ['prvView'],
cache: 'pre',//菜单页面,跳转的时候直接清空原来缓存,重新开始缓存页面
},
},
// 加入构件包
{
path: 'package/:id/addComponent',
name: 'packageAddComponent',
component: PackageAddComponent,
meta: {
auth: ['prvView'],
cache: true,//非菜单页面需要缓存的路由
},
props: (route) => ({ pkgId: route.params.id }),
},
]
router.beforeEach(async (to, from) => {
cachePage(to)
})