这出现的原因是多级路由导致的,就是router-view嵌套 在层级不同的router-view中切换tag会出现缓存数据失效的问题。目前keep-alive可以有效缓存一级,二级的路由菜单,3级以上菜单并不能做到缓存,这里提供一个解决方案:
在cachedViews中手动加上一级菜单和三级菜单之间,缺失的二级菜单的名字,这样二级菜单下的组件就会缓存了
实列代码如下:
const _import = require('@/router/_import_prodection');//获取组件的方法
import {tree} from '@/utils/treeDate'
import Layout from '@/views/layout'
import EmptyTemplate from '@/views/layout/EmptyTemplate'
export function filterAsyncRouter(routerlist) {
const routerlists=tree(routerlist )
//获取路由信息
function getRouter(routerlists){
routerlists.forEach(e => {
// 删除无用属性
delete e.catalogCode
delete e.catalogOrder
delete e.endpoints
delete e.fullOrder
// delete e.permName
// delete e.id
// delete e.parentId
e.name=e.catalogName
if (e.parentId === 0||e.children) {//Layout组件特殊处理
//路径为空时会因为undefind报错,给个默认值来解决
e.path = e.url||'nopath'
if(e.url.split('/').length>2){
/*
*处理多层级路的时候给了一个空模板
*处理的原理就是多层级的路由的根节点都给上空模板
*利用keep-alive能缓存一二级的原理,可以做到缓存每个多层级路由根节点下的所有子节点
*通过e.children判断是否存在子节点,若存在当前节点就采用空模板
*举公司路由例子
*'/system': '系统管理',(一级)
*'/system/processManage': '流程管理',(二级)
*'/system/processManage/processConfiguration': '流程配置',(三级)
*'/system/processManage/processMonitor': '流程监控',
*'/system/processManage/processFristaid': '流程急救箱',
*'/system/processManage/waitingCenter': '待办中心',
*系统管理和流程管理都属于根节点因为都有子节点,通过e.url.split('/')的长度判断
*属于一级菜单用Layout模板
*属于二级菜单以上用EmptyTemplate,后面递归可以支持无限级路由的缓存
*这里解释为什么二级菜单用空模板,因为二级的模板会嵌入在一级的模板内
*保证不会出现其他样式和内容上的冲突
*/
e.component = EmptyTemplate
}else{
e.component = Layout
}
e.icon='setting-fill'
} else {
e.icon='circle'
//_import模块的代码module.exports = file => () => import('@/views' + file + '/index'),
//当路由没有子节点时,使用他们自己路径,这里要注意下匹配的是当前文件下的index页面
e.component = _import(e.url)
//路径为空时会因为undefind报错,给个默认值来解决
e.path = e.url.split('/')[2]||'nopath'
}
// delete e.parentId
delete e.url
// if (e.redirect === '') {
// delete e.redirect
// }
if (e.icon !== '' && e.title !== '') { // 配置 菜单标题 与 图标
e.meta = {
// title: e.catalogName 中文名称
// catalogEngName 英文名称
title: e.catalogEngName,
titleZh:e.catalogName,
icon: e.icon
}
}
delete e.catalogName
delete e.icon
delete e.title
// delete e.name//由于名字的存在导致named 错误 删掉
if (e.children != null) {
// 存在子路由就递归
getRouter(e.children)
}
})
return routerlists
}
const getRouters=getRouter(routerlists)
// return asyncRouterMap
return getRouters
}
空模板的代码如下:
<template>
<div>
<app-main/>
</div>
</template>
<script>
import { AppMain} from './components'
export default {
name:'EmptyTemplate',
components:{AppMain}
}
</script>
AppMain.vue代码
<template>
<section class="app-main">
<transition mode="out-in" name="fade-transform">
<keep-alive :include="cachedViews" exclude="redirect">
<router-view :key="key" />
</keep-alive>
</transition>
</section>
</template>
<script>
export default {
name: 'AppMain',
computed: {
cachedViews () {
console.log(this.$store.state.tagsView.cachedViews, 'cachedViews')
return this.$store.state.tagsView.cachedViews
},
key () {
return this.$route.path
// return this.$route.fullPath
}
}
}
</script>
tagsViewd.js关键代码,在cachedViews中加入空模板的name
const state = {
visitedViews: [],
cachedViews: ['EmptyTemplate']
}