Vue 使用 vue-router 時,多級嵌套路由緩存問題處理
對于三級菜單(或多級嵌套路由),vue 都是 通過 keep-alive 組件來實現路由組件的緩存。
有時候三級或者多級路由時,會出現失效情況。以下是三級菜單緩存的例子。
最后會有驚喜!
1.配置嵌套路由
在 vue-router 中,嵌套路由需要正確配置 children 屬性,并且每個路由組件都需要有唯一的 name,很重要。很重要。很重要。。
const routes = [{path: '/',component: Layout, // 布局組件children: [{path: '/menu1/path/',component: Menu1, // 一級菜單children: [{path: '/submenu1/path',component: SubMenu1, // 二級菜單children: [{path: 'item1',component: Item1, // 三級菜單name: 'Item1', // 確保每個組件有唯一的 namemeta: {noCache: false, //自定義參數,是否緩存}},{path: 'item2',component: Item2,name: 'Item2',meta: {noCache: false,}},],},],},],},
];
2. 在嵌套路由中使用 router-view
在每一級菜單的組件中,都需要使用 router-view 來渲染子路由,記住是每一級
Menu1.vue
<template><div><h2>Menu 1</h2><keep-alive><router-view></router-view> <!-- 渲染二級菜單 --></keep-alive></div>
</template>
SubMenu1
<template><div><h3>SubMenu 1</h3><keep-alive><router-view></router-view> <!-- 渲染三級菜單 --></keep-alive></div>
</template>
3. 使用 keep-alive 緩存嵌套路由
在頂級組件(如 Layout.vue)中,用 包裹 ,確保所有嵌套路由組件都能被緩存。
如果只想緩存特定的嵌套路由組件,可以通過 include 或 exclude 屬性來實現。
Layout.vue
<template><div><nav><!-- 菜單導航 --><router-link to="/menu1/submenu1/item1">Item 1</router-link><router-link to="/menu1/submenu1/item2">Item 2</router-link></nav><!-- 使用 keep-alive 緩存所有嵌套路由 --><keep-alive :include="cachedViews" :exclude="notCacheName"><router-view></router-view></keep-alive></div>
</template><script>
export default {name: "clientManager",computed: {cachedViews() {return [...this.$store.state.tagsView.cachedViews];},key() {return this.$route.path;},notCacheName() {return [this.$route.meta && this.$route.meta.noCache ? this.$route.name : "",];},},
};
</script>
此處有疑問點:
我查到的文檔,基本上都是說在 頂級組件 Layout.vue 里面配置 keep-alive即可,下級的不用配置。
但是經過我測試,發現每一級都要配置 keep-alive,請看第二步。不配置的話,緩存就是不起作用。不知道為啥?
我是配置了每一級的,然后就可以了。此次請大家幫我解一下疑惑,萬分感謝!
4. 最后的頁面
<template><div><h4>Item 1</h4><p>This is Item 1.</p></div>
</template><script>
export default {name: 'Item1',activated() {console.log('Item1 被激活');},deactivated() {console.log('Item1 被停用');},
};
</script>
菜單緩存失敗的原因
- 路由配置不正確,導致組件被重復渲染。
- 組件沒有唯一的 name。
- 嵌套路由的 沒有正確渲染
- 確認頁面的 name 是否和 路由配置定義頁面的 name 是否相同,不同肯定失敗。