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的链接的时候,它又会重新复用回原本的组件。
2 把三级(概念上的)转化为二级(真实)
在这里想来,如果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来存储数据比较好。
到此这篇关于vue-template-admin三级路由无法缓存的解决方案的文章就介绍到这了,更多相关vue-template-admin三级路由缓存内容请搜索易盾网络以前的文章或继续浏览下面的相关文章希望大家以后多多支持易盾网络!