Vue3嵌套路由中使用keep-alive緩存多層的實現(xiàn)
前言
keep-alive
是Vue中的緩存標簽, 組件在標簽中的內(nèi)容會被緩存下來;但是在多層嵌套的router-view
中, 只能緩存到該層下的router-view
, 由于路由嵌套比較常見,所以這里提供兩種我覺得OK的解決方案。
解決思路
- 路由層級扁平化,在路由守衛(wèi)中執(zhí)行一個拍平的函數(shù),將需要緩存的路由提升到第一層,這樣處理會影響到路由層級,最直白的影響如對 面包屑 等功能有直接影響
- 把所有的
router-view
都通過keep-alive
包裹起來, 通過keep-alive
的include
,exclude
來判斷是否需要緩存。
Demo項目結(jié)構(gòu)
router.ts
路由的結(jié)構(gòu)大概是這樣的 Layout > TableManage > (List, Detail, Add...)
路由層級扁平化
在路由的 afterEach 執(zhí)行一個扁平化方法, 舉例:
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 { /* has no token */ 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) }) /** * 遞歸處理多余的 layout : <router-view>, * 讓需要訪問的組件保持在第一層 index : <router-view> 之下 */ 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方法中去移除,弊端很明顯, 路由的結(jié)構(gòu)受到了影響
給所有的 router-view 都嵌套上 keep-alive
這是我比較推薦的一種方法, 沒什么副作用,也不麻煩, 畢竟所有的 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>
這樣就可以實現(xiàn)嵌套路由的緩存了。 附上演示
到此這篇關(guān)于Vue3嵌套路由中使用keep-alive緩存多層的實現(xiàn)的文章就介紹到這了,更多相關(guān)Vue3 keep-alive緩存多層內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Vue使用axios進行數(shù)據(jù)異步交互的方法
大家都知道在Vue里面有兩種出名的插件能夠支持發(fā)起異步數(shù)據(jù)傳輸和接口交互,分別是axios和vue-resource,同時vue更新到2.0之后,宣告不再對vue-resource更新,而是推薦的axios,今天就講一下怎么引入axios,需要的朋友可以參考下2024-01-01vue如何實現(xiàn)el-select下拉選項的懶加載
這篇文章主要介紹了vue如何實現(xiàn)el-select下拉選項的懶加載,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-04-04vue前端優(yōu)雅展示后端十萬條數(shù)據(jù)面試點剖析
這篇文章主要為大家介紹了vue前端優(yōu)雅展示后端十萬條數(shù)據(jù)的考點剖析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-07-07