解决vue项目中keep-alive不能缓存多层级路由问题

解决vue项目中keep-alive不能缓存多层级路由问题

看了很多文档,都是把嵌套多级路由简化(keep-alive满足二级/一级菜单缓存),菜单数据和路有数据分离开,这种方案解决起来相对复杂一些,下面的方法相对简单一些,我是看了这篇文章,结合自己的项目稍作修改.下边也有自己遇到的问题及解决方法.

需求介绍

自己项目的图片不便粘贴,我还是引用原博主的图片
解决vue项目中keep-alive不能缓存多层级路由问题_第1张图片
项目中使用的是3级路由,要实现三级菜单来回跳转保存状态(并且跨二级菜单间的三级菜单页面切换也需要保存状态)
咱们首先想到的是使用keep-alive标签来实现此功能.
在3级router-view的index.vue文件添加keep-alive标签






这样只能实现二级菜单内三级菜单页面切换状态可以保存,跨二级菜单间的三级菜单页面切换也需要保存状态是不能实现的.

解决方案

1.把含有3级router-view的文件改为


2.把之前3级router-view的index.vue中keep-alive展示逻辑,包括:include="tagNames"属性逻辑,都写到2级router-view的vue文件中,在我的项目中此文件为layout文件夹中index.vue,layout为项目中的整体布局文件.代码如下

          
            
          
        
        
          
        
computed: {
    ...mapGetters("history", ["tagNames"]),
 },
3.在全局路由守卫中加上这段代码:(仅仅只是满足三级菜单缓存)

解决vue项目中keep-alive不能缓存多层级路由问题_第2张图片

if (to.matched && to.matched.length > 2) {
   for (let i = 0; i < to.matched.length; i++) {
     const element = to.matched[i]
     if (element.components.default.name === 'Blank') {
       to.matched.splice(i, 1)
     }
   }
 }

我按照这种方案实现的时候,出现了两个问题
1.刷新页面后,首次切换页面并没有保存状态,切换后再回来操作才能保存.
2.如果页面中存在面包屑,由于把路由层级splice删掉的一级,导致面包屑层级有问题.

分析

问题1:在页面刷新的时候element.components.default.name是空值,导致to.matched.splice(i, 1)语句不执行.具体什么原因导致的,我没有深究,以后有人发现是啥导致的,可以留言给我.
问题2:由于把路由层级splice删掉的一级,我项目中面包屑正好是用to.matched路由层级遍历生成的所以出现了问题

思路

解决问题1
用数组存放需要保存功能的二级页面名称,只要三级路由结构的路由中含有这些名称,就把三级路由结构中的二级路由手动删除.
解决问题2
在删减层级之前把路由层级保存起来,用于面包屑的展示
直接上代码


router.beforeEach(async(to, from, next) => {
.........
//缓存中保存原有的3级路由title值存入缓存,用于面包屑路径显示(解决问题2)
    let matchedRouter = ["controlManagement","...."]      //存放需要保存功能的页面名称,这个地方按照你的项目中二级路由页面名称来确定
    for (let i = 0; i < to.matched.length; i++) {
        const element = to.matched[i]
        matchedRouter.push(element.meta.title)
    }
    sessionStorage.setItem("matchedRouter",JSON.stringify(matchedRouter)) 
    //修复三级路由不能保存状态问题(解决问题1)
    if (to.matched && to.matched.length > 2) {
        for (let i = 0; i < to.matched.length; i++) {
            const element = to.matched[i]
            const Index = saveBlankPages.findIndex((item) => {return item === element.name})
            if (Index>=0) {
                to.matched.splice(i, 1)
            }
        }
    }
    ..........

面包屑代码


  {{ item }}

watch: {
    $route(){
      let matchedRouter = JSON.parse(sessionStorage.getItem("matchedRouter"))
      this.matchedRouter = matchedRouter;
    }
  },

希望对你有帮助

你可能感兴趣的:(vue-router,keep-alive,keep-alive,前端)