vue中keep-alive组件实现多级嵌套路由的缓存
现状(问题):keep-alive 组件对第三级及以上级的路由页面缓存失效探索方案:方案1、直接将路由扁平化配置,都放在一级或二级路由中方案2、再一层缓存组件用来过渡,并将其name配置到include中实现方式方案1不需要例子,按规则配置路由就行重点介绍方案2因为我用了vue-element-admin做了架构,并且项目中我将菜单和路由全部通过服务端返回做了统一配置,所以我只能用方案2来实现。直
·
-
现状(问题):
keep-alive 组件对第三级及以上级的路由页面缓存失效
-
探索方案:
方案1、直接将路由扁平化配置,都放在一级或二级路由中 方案2、再一层缓存组件用来过渡,并将其name配置到include中
-
实现方式
方案1不需要例子,按规则配置路由就行重点介绍方案2 因为我用了vue-element-admin做了架构,并且项目中我将菜单和路由全部通过服务端返回做了统一配置,所以我只能用方案2来实现。
直接看原有代码(问题代码)
// src/layout/component/AppMain.vue
<template>
<section class="app-main">
<transition name="fade-transform" mode="out-in">
<keep-alive :include="cachedViews">
<router-view :key="key" />
</keep-alive>
</transition>
</section>
</template>
<script>
export default {
name: 'AppMain',
computed: {
cachedViews() {
return this.$store.state.tagsView.cachedViews
},
key() {
return this.$route.path
}
}
}
</script>
我从后端那到数据后,根据树形结构做了处理(在store里写的,只展示出关键代码)
// 拿到数据先循环第一层将Layout付给组件
generateRoutes({ commit }, routeList) {
return new Promise(resolve => {
routeList.forEach(items => {
items.component = Layout
// 如果有子菜单直接再循环赋值
items.children = changeAsyncRoutes(items.children)
})
commit('SET_ROUTES', routeList)
resolve(routeList)
})
}
function changeAsyncRoutes(routes) {
const res = []
routes.forEach(route => {
const tmp = { ...route }
if (tmp.children && tmp.children.length !== 0) {
// 若有子级 先创建router-view容器,再去递归(重点重点重点)
tmp.component = {
render: c => c('router-view')
}
tmp.children = changeAsyncRoutes(tmp.children)
} else {
// 没有子级菜单直接将component字符串解析成组件对象
tmp.component = importMethod(tmp.component)
}
res.push(tmp)
})
return res
}
这种写法已经很完美了,可惜,我遇到了三级菜单不能缓存的问题
直接上解决问题的代码
1、新建MenuMain.vue组件如下
// src/layout/component/MenuMain.vue
// 提供多级菜单的容器
<template>
<keep-alive :include="cachedViews">
<router-view :key="key" />
</keep-alive>
</template>
<script>
export default {
name: 'MenuMain', // 必须命名
computed: {
cachedViews() {
return this.$store.state.tagsView.cachedViews
},
key() {
return this.$route.path
}
}
}
</script>
2、将此容器取代处理数据时render的 router-view 容器
// 引入组件
import MenuMain from '@/layout/components/MenuMain'
function changeAsyncRoutes(routes) {
const res = []
routes.forEach(route => {
const tmp = { ...route }
if (tmp.children && tmp.children.length !== 0) {
// 注意看着里
tmp.component = MenuMain
// {
// render: c => c('router-view')
// }
tmp.children = changeAsyncRoutes(tmp.children)
} else {
tmp.component = importMethod(tmp.component)
}
res.push(tmp)
})
return res
}
3、把store中的 cachedViews 数组中始终保存MenuMain组件的名称
cachedViews: ['MenuMain']
完!
随笔而记,讲述不清,有问必答!
更多推荐
已为社区贡献2条内容
所有评论(0)