解决基于 keep-alive 的后台多级路由缓存问题


Posted in Javascript onDecember 23, 2020

用过 vue-element-admin 的同学一定很清楚,路由的配置直接关系侧边栏导航菜单的展示,也得益于这种设计思路,几乎大部分后台框架都采用这个方案,当然也包括了我写的 Fantastic-admin 这个中后台框架。

但这个方案有个明显的问题,就是为了实现多级侧边栏导航菜单,则需要将路由配置成多级嵌套的形式,一旦超过两级,达到三级甚至更多级,就需要增加一个空布局页面(Empty.vue)用来给 component 使用,仅仅是为了生成层级菜单。此时就出现了一个问题,因为 keep-alive 是在 Layout 上处理的,所以超过两级以上的路由都会变得难以处理,也没有一个相对完美的解决方案。

在思考并解决这个问题之前,我们先来看下页面大致结构:

+------------------------------+
| Layout            |
| +------------------------+ |
| | Empty         | |
| | +------------------+ | |
| | | Page       | | |
| | +------------------+ | |
| +------------------------+ |
+------------------------------+

首先 keep-alive 是在 Layout 上进行处理,如果不缓存 Empty ,则 Empty 下面的页面将无法被缓存,如果缓存 Empty ,又会导致 Empty 里面的所有页面都被缓存,无法按需清除,相信接触过的同学肯定感同身受其中的大坑。

解决基于 keep-alive 的后台多级路由缓存问题

解决思路

其实有一个相对清晰简单的解决思路,既然缓存二级路由是没问题,而超过二级的中间层级页面也是没太大意义的,那为什么不将路由直接处理成二级,这样页面显示也就是二级的结构。

+------------------------------+        +------------------------------+
| Layout            |        | Layout.vue          |
| +------------------------+ |        | +------------------------+ |
| | Empty         | | +----------> | | Page          | |
| | +------------------+ | |        | |            | |
| | | Page       | | |        | |            | |
| | +------------------+ | |        | |            | |
| +------------------------+ |        | +------------------------+ |
+------------------------------+        +------------------------------+

这里需要注意,路由配置还是保持多级嵌套的形式,而这个配置并非最终注册使用的路由,仅仅是提供侧边栏导航菜单使用,同时再生成一份用于动态注册路由的数据,图例如果没看明白的话,可以看下面两组数据。

// 原始数据(用于侧边栏导航菜单)
{
  path: '/users',
  meta: {
    title: '用户管理'
  },
  children: [
    {
      path: 'clients',
      meta: {
        title: '客户管理'
      },
      children: [
        {
          path: 'list',
          meta: {
            title: '客户列表'
          }
        },
        {
          path: 'detail',
          meta: {
            title: '客户详情'
          }
        }
      ]
    }
  ]
}

// 处理后数据(用于动态注册路由)
{
  path: '/users',
  meta: {
    title: '用户管理'
  },
  children: [
    {
      path: 'clients/list',
      meta: {
        title: '客户列表'
      }
    },
    {
      path: 'clients/detail',
      meta: {
        title: '客户详情'
      }
    }
  ]
}

通过一个递归函数就可以处理好路由的数据,但这还不够,因为还需要处理面包屑导航。

原有的面包屑导航是通过 $route.matched 可以获取到嵌套路由每一层级的信息,而当路由被处理成两级后,也就无法通过 $route.matched 进行显示了,所以在处理路由数据的同时,也需要处理面包屑导航的信息。大致最终会处理成这样:

{
  path: '/users',
  meta: {
    title: '用户管理'
  },
  children: [
    {
      path: 'clients/list',
      meta: {
        title: '客户列表',
        breadCrumb: [
          { path: '/users', title: '用户管理' },
          { path: 'clients', title: '客户管理' },
          { path: 'list', title: '客户列表' }
        ]
      }
    },
    {
      path: 'clients/detail',
      meta: {
        title: '客户详情',
        breadCrumb: [
          { path: '/users', title: '用户管理' },
          { path: 'clients', title: '客户管理' },
          { path: 'detail', title: '客户详情' }
        ]
      }
    }
  ]
}

这样一来,通过 $route.meta.breadcrumb 就可以获取任意某个路由的完整面包屑导航信息了。最终效果如下:

解决基于 keep-alive 的后台多级路由缓存问题

通过图片可以看到,这种方案也还是有一定的限制,就是路由被处理成二级后,多级嵌套关系不存在了,也就是不能在 Empty 里写任何代码,因为都会被忽略掉,只保留顶级和最深层的底级两个路由。

当然通过实际情况考虑,这种限制并没有大问题,因为在后台系统里,本身模块相对独立,即便侧边栏导航菜单是嵌套层级关系的,在右侧内容展示区域,几乎都是独立模块展示,无需嵌套。

实例代码

本文主要是讨论实现思路,相关代码可在 Fantastic-admin 里查看,核心代码在这,点击查看。

到此这篇关于解决基于 keep-alive 的后台多级路由缓存问题的文章就介绍到这了,更多相关 keep-alive多级路由缓存 内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Javascript 相关文章推荐
一些主流JS框架中DOMReady事件的实现小结
Feb 12 Javascript
js将控件隐藏的方法及display属性介绍
Jul 04 Javascript
JS实现简单的键盘打字的效果
Apr 24 Javascript
Javascript实现div层渐隐效果的方法
May 30 Javascript
跟我学习javascript的for循环和for...in循环
Nov 18 Javascript
AngularJS表单验证功能
Oct 19 Javascript
解决vue单页路由跳转后scrollTop的问题
Sep 03 Javascript
使用vue2实现带地区编号和名称的省市县三级联动效果
Nov 05 Javascript
webpack的pitching loader详解
Sep 23 Javascript
JS实现排行榜文字向上滚动轮播效果
Nov 26 Javascript
keep-Alive搭配vue-router实现缓存页面效果的示例代码
Jun 24 Javascript
深入了解JavaScript词法作用域
Jul 29 Javascript
jQuery实现增删改查
Dec 22 #jQuery
jQuery实现本地存储
Dec 22 #jQuery
jQuery实现电梯导航模块
Dec 22 #jQuery
jQuery实现tab栏切换效果
Dec 22 #jQuery
Vue3 实现双盒子定位Overlay的示例
Dec 22 #Vue.js
详解Vue的异步更新实现原理
Dec 22 #Vue.js
jQuery+ajax实现文件上传功能
Dec 22 #jQuery
You might like
将RTF格式的文件转成HTML并在网页中显示的代码
2006/10/09 PHP
php定时计划任务与fsockopen持续进程实例
2014/05/23 PHP
一些常用的Javascript函数
2006/12/22 Javascript
js 操作符实例代码
2009/10/24 Javascript
jqPlot 基于jquery的画图插件
2011/04/26 Javascript
浅析jquery ajax异步调用方法中不能给全局变量赋值的原因及解决方法
2014/01/10 Javascript
javascript生成随机数的方法
2014/05/16 Javascript
关闭页面window.location事件未执行的原因及解决方法
2014/09/01 Javascript
JavaScript中使用typeof运算符需要注意的几个坑
2014/11/08 Javascript
jQuery中用dom操作替代正则表达式
2014/12/29 Javascript
自定义函数实现IE7与IE8不兼容js中trim函数的问题
2015/02/03 Javascript
浅谈js中对象的使用
2016/08/11 Javascript
jQuery插件echarts设置折线图中折线线条颜色和折线点颜色的方法
2017/03/03 Javascript
jQuery实现常见的隐藏与展示列表效果示例
2018/06/04 jQuery
详解React之父子组件传递和其它一些要点
2018/06/25 Javascript
使用layui实现树形结构的方法
2019/09/20 Javascript
vue-preview动态获取图片宽高并增加旋转功能的实现
2020/07/29 Javascript
JavaScript实现无限轮播效果
2020/11/19 Javascript
[46:25]DOTA2上海特级锦标赛主赛事日 - 4 败者组第五轮 MVP.Phx VS EG第二局
2016/03/05 DOTA
[34:39]Secret vs VG 2018国际邀请赛淘汰赛BO3 第二场 8.23
2018/08/24 DOTA
python 中if else 语句的作用及示例代码
2018/03/05 Python
使用pandas对两个dataframe进行join的实例
2018/06/08 Python
Python datetime和unix时间戳之间相互转换的讲解
2019/04/01 Python
OpenCV 模板匹配
2019/07/10 Python
在VS2017中用C#调用python脚本的实现
2019/07/31 Python
python飞机大战pygame游戏背景设计详解
2019/12/17 Python
基于css3的属性transition制作菜单导航效果
2015/09/01 HTML / CSS
html5 Canvas绘制线条 closePath()实例代码
2012/05/10 HTML / CSS
美国一家全面的在线零售鞋类公司:SHOEBACCA
2017/01/06 全球购物
公司聘任书模板
2014/03/29 职场文书
求职信格式要求
2014/05/23 职场文书
个人总结与自我评价2015
2015/03/11 职场文书
学习十八大的感悟
2015/08/11 职场文书
《桂花雨》教学反思
2016/02/19 职场文书
NodeJs内存占用过高的排查实战记录
2021/05/10 NodeJs
css弧边选项卡的项目实践
2023/05/07 HTML / CSS