vue-template-admin三级路由无法缓存的解决方案
为什么三级会缓存不了在src/layout/AppMain组件:keep-alive的组件依赖cachedViews,cachedViews是store中的一个状态,cachedViews的逻辑在src/layout/TagView当路由变更时就会调用addViewTags,addViewTag会根据匹配的路由name属性进行缓存。而用到三级路由的时候,拿到name只能时第三级路由...
1. 为什么三级会缓存不了
在src/layout/AppMain组件:
keep-alive的组件依赖cachedViews,cachedViews是store中的一个状态,
cachedViews的逻辑在src/layout/TagView
当路由变更时就会调用addViewTags,addViewTag会根据匹配的路由name属性进行缓存。而用到三级路由的时候,拿到name只能时第三级路由的name,二级路由组件的名字会丢失,keep-alive就不会进行缓存。
知道原因之后,第一个想法就是把二级路由的name也加上去就好了。要实现这个也很简单,只需要获取到matched属性就可以拿到匹配到的路由组件,把它加入到cachedViews数组就好了。但是有个问题就是,假设这里有个二级路由1-1,三级路由1-1-1,1-1-2,当要关掉1-1-1组件时,你到底要不要把1-1给删了,如果删了,缓存能顺利失效,但是如果你之前是打开了1-1-2,缓存的路由就会失效,因为它是依赖1-1的。如果不删的话,在侧边栏打开1-1-1的链接的时候,它又会重新复用回原本的组件。
3. 把三级(概念上的)转化为二级(真实)
在这里想来,如果1-1-1,1-1-2,其实只是因为分在同类别里,两者如果没有实际共享的数据,那可以考虑把1-1的路由组件关掉,在我实践的项目就是如此,1-1-1和1-1-2只是同属在二级菜单下,并没有共享数据。但是生成菜单的时候是用router表的,那么生成菜单的用原本的,生成路由的时候用替换的。
下面是demo代码:
将要被替换的路由加上noCompoent属性。
function delteFakeParent(router,prefix) {
var newRouter = { ...router }
if(prefix){
newRouter.path = prefix + '/' + router.path
}
if (!router.children) return newRouter
var children = []
if (router.noCompoent) {
for (let i = 0; i < router.children.length; i++) {
const item = delteFakeParent(router.children[i], newRouter.path)
if (Array.isArray(item)) {
item.forEach(el => {
children.push(el)
})
}else{
children.push(item)
}
}
newRouter = children
} else {
for (let i = 0; i < router.children.length; i++) {
const item = delteFakeParent(router.children[i])
if (Array.isArray(item)) {
item.forEach(el => {
children.push(el)
})
}
}
newRouter.children = children
}
return newRouter
}
var backendManageRouter1 = {
name: 'BackendManage',
meta: {
title: '后台管理',
icon: 'index-management'
},
children: [{
path: 'user-manage',
name: 'UserManage',
noCompoent: true,
meta: {
title: '用户管理',
icon: 'rule-definition'
},
alwaysShow: true,
children: [{
path: 'user',
name: 'User',
meta: {
title: '用户管理',
icon: 'quality-control'
},
noCompoent: true,
children: [
{
path: 'a',
name: 'ad',
meta: {
title: 'ad管理',
icon: 'quality-control'
},
}
]
}, {
path: 'role',
name: 'Role',
meta: {
title: '角色管理',
icon: 'rule-task-monitor'
}
}]
}]
}
delteFakeParent这个函数做的就是创建一个router副本,遍历它的children,当这个路由被标记为noCompoent: true,就把它替换成它的children,回溯的过程中如果router是一个数组就代表这个router是被替换过,那么就遍历它,把它每一项放到router.children里面,这样就可以做到跟它其他children平级。
修改了这个之后要记着把真实router和菜单router同时暴露出去,菜单的项目是读取store中的permission.js的routers,那么这里set-router一方面要处理真是router和菜单router,需要增加一个state
3. 使用vuex存储数据
上面那个方案也只是针对二级路由组件不需要显示出来,那么可以放到一级路由的children里面,但是如果是有需要的话,还是使用vuex来存储数据比较好。
更多推荐
所有评论(0)