keep-alive多级路由缓存问题

2,157 阅读2分钟

keep-alive多级路由缓存问题

1.问题描述

对账中心当便捷导航菜单最后两个是同一模块且是三级及以上菜单时,正常切换两个便捷页签时是可以正常缓存的,但删除最后一个页签时,此时另一个页签页面此时已经不缓存了。

2.原因分析

keep-alive默认支持缓存是两级,对三级及以上层级的页面缓存失效,之前的处理方式为: 监听到路由变化后,将当前的路由的标识及父级标识一起存起来,当多个页面存在时,关闭其中一个页面,也会将本身及父级的标识一起删掉,此时数组中已无父级标识,其他同级页面的缓存将失效。

3.解决思路

将路由配置表的所有路由拆成两个操作,一是保持原样用于菜单的展示,二是对路由配置表进行扁平化处理,将所有的路由处理成二级路由,这样keep-alive就能默认支持缓存了。

4.处理过程

  • 拿到完整的路由配置

    const modules = []
    files.keys().forEach(key => {
        const filesObj = files(key).default || files(key)
        Object.keys(filesObj).forEach(keyOne => {
            modules.push(filesObj[keyOne])
        })
    })
    
  • 操作完成路由配置

    export const menuList = modules;  // 用于菜单展示const routerList = formatTwoStageRoutes(formatFlatteningRoutes(modules)); // 将路由扁平化为二级路由const router = new VueRouter({
        scrollBehavior: () => ({ y: 0 }),
        mode: 'history',
        base: process.env.BASE_URL,
        routes: routerList, // 在路由配置项中使用扁平化处理后的路由
    })
    
  • 扁平化方法

    ​
    export const formatFlatteningRoutes =(routesList => {
      if (routesList.length <= 0) return routesList;
      let list = [];
      routesList.forEach(v => {
        if(v.path === '/') {
          // 用于添加初试layout和首页,其他各中心配置过滤掉layout及父节点,只保留children内路由
          list.push(v);
          list = list.concat(formatFlatteningRoutes(v.children))
        } else if (v.children && v.children.length > 0) {
          list = list.concat(formatFlatteningRoutes(v.children))
        } else {
          list.push(v);
        }
      })
      return list;
    })
    ​
    export const formatTwoStageRoutes = list => {
      if (list.length <= 0) return list;
      const routerList = [];
      list.forEach(v => {
        if (v.path === '/') {
          routerList.push({
            component: v.component,
            name: v.name,
            path: v.path,
            redirect: v.redirect,
            meta: v.meta,
            children: []
          })
        } else if (v.path === '/login' || v.path === '/showcasePage') {
          // 不需要配置layout的页面
          routerList.push(v)
        } else {
          routerList[0].children.push({ ...v })
        }
      })
      return routerList;
    }