目录前言Demo项目结构路由层级扁平化给所有的 router-view 都嵌套上 keep-alive前言 keep-alive是Vue中的缓存标签, 组件在标签中的内容会被缓存下来
keep-alive
是Vue中的缓存标签, 组件在标签中的内容会被缓存下来;但是在多层嵌套的router-view
中, 只能缓存到该层下的router-view
, 由于路由嵌套比较常见,所以这里提供两种我觉得OK的解决方案。
解决思路
router-view
都通过 keep-alive
包裹起来, 通过keep-alive
的include
, exclude
来判断是否需要缓存。router.ts
路由的结构大概是这样的 Layout > TableManage > (List, Detail, Add...)
在路由的 afterEach 执行一个扁平化方法, 举例:
import router from '@/router/index'
import PageTitleUtils from '@/utils/PageTitleUtils'
import { ElMessage } from 'element-plus'
import useStore from '@/store/index'
import type { RouteLocationNORMalized, NavigationGuardNext } from 'vue-router'
import NProgress from 'nprogress'
import 'nprogress/nprogress.CSS'
NProgress.configure({ showSpinner: false }) // NProgress Configuration
const { user, routeStore } = useStore()
const whiteList = ['/login'] // no redirect whitelist
router.beforeEach(async (to: RouteLocationNormalized, from: RouteLocationNormalized, next: NavigationGuardNext) => {
NProgress.start()
if (user.hasToken()) {
if (to.path === '/login') {
next({ path: '/' })
NProgress.done()
} else {
if (user.hasUserInfo()) {
next()
NProgress.done()
} else {
try {
await user.getUserInfo()
await routeStore.setRoutes()
next({ ...to, replace: true })
NProgress.done()
} catch (error: any) {
routeStore.resetRoutes()
user.resetUserInfo()
ElMessage.error(error || 'Has Error')
next(`/login?redirect=${to.fullPath}`)
NProgress.done()
}
}
}
} else {
if (whiteList.indexOf(to.path) !== -1) {
// in the free login whitelist, Go directly
next()
NProgress.done()
} else {
// other pages that do not have permission to access are redirected to the login page.
next(`/login?redirect=${to.fullPath}`)
NProgress.done()
}
}
})
router.afterEach((to: any) => {
NProgress.done()
// set page title
const { meta }: any = to
document.title = PageTitleUtils.getPageTitle(meta.title)
// delayering router
delayeringRoute(to)
})
function delayeringRoute(to: RouteLocationNormalized) {
if (to.matched && to.matched.length > 2) {
for (let i = 0; i < to.matched.length; i++) {
const element = to.matched[i]
// 移除多余的 layout, 也许你项目中并不叫 layout ,自行修改此处
if (element.components?.default.name === 'layout') {
to.matched.splice(i, 1)
handleKeepAlive(to)
}
}
}
}
以上代码示例中, delayeringRoute 是移除多余 layout 的方法, 在路由的afterEach方法中去移除,弊端很明显, 路由的结构受到了影响
这是我比较推荐的一种方法, 没什么副作用,也不麻烦, 毕竟所有的 router-view
都一样,如果你使用的IDE是vscode
,可以直接把这段代码写进项目中的代码片段, 方便使用。
Layout的Main
<script lang="ts" setup name="AppMain">
import { useRoute } from 'vue-router'
import useStore from '@/store';
import { storeToRefs } from 'pinia';
const route = useRoute()
const { tagview } = useStore()
const { cacheList } = storeToRefs(tagview)
</script>
<template>
<div class="app-main">
<router-view v-slot="{ Component }">
<keep-alive :include="cacheList">
<component :is="Component" :key="route.fullPath" />
</keep-alive>
</router-view>
</div>
</template>
<style scoped lang="scss">
</style>
其他嵌套的路由, 不管几层,都可以这样处理
<script lang="ts" setup name="TableManage">
import { useRoute } from 'vue-router'
import useStore from '@/store';
import { storeToRefs } from 'pinia';
import { onMounted } from 'vue';
const route = useRoute()
const { tagview } = useStore()
const { cacheList } = storeToRefs(tagview)
onMounted(() => {
tagview.addCacheList('TableManage')
})
</script>
<template>
<router-view v-slot="{ Component }">
<keep-alive :include="cacheList">
<component :is="Component" :key="route.fullPath" />
</keep-alive>
</router-view>
</template>
这样就可以实现嵌套路由的缓存了。 附上演示
到此这篇关于vue3嵌套路由中使用keep-alive缓存多层的实现的文章就介绍到这了,更多相关Vue3 keep-alive缓存多层内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!
--结束END--
本文标题: Vue3嵌套路由中使用keep-alive缓存多层的实现
本文链接: https://lsjlt.com/news/209751.html(转载时请注明来源链接)
有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341
2024-01-12
2023-05-20
2023-05-20
2023-05-20
2023-05-20
2023-05-20
2023-05-20
2023-05-20
2023-05-20
2023-05-20
回答
回答
回答
回答
回答
回答
回答
回答
回答
回答
0