IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> 解决vue项目中keep-alive不能缓存多层级路由问题 -> 正文阅读

[JavaScript知识库]解决vue项目中keep-alive不能缓存多层级路由问题

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

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

需求介绍

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

<template>
  <div>
    <keep-alive :include="tagNames">
      <router-view v-if="$route.meta.keepAlive"></router-view>
    </keep-alive>
    <router-view v-if="!$route.meta.keepAlive"></router-view>
  </div>
</template>

<script>
import { mapGetters } from "vuex";
export default {
  name: "Blank",
  computed: {
    ...mapGetters("history", ["tagNames"]),
  },
};
</script>
<style lang="scss"></style>

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

解决方案

1.把含有3级router-view的文件改为
<template>
    <router-view />
</template>
<script>
export default {
  name: 'Blank'
}
</script>
2.把之前3级router-view的index.vue中keep-alive展示逻辑,包括:include="tagNames"属性逻辑,都写到2级router-view的vue文件中,在我的项目中此文件为layout文件夹中index.vue,layout为项目中的整体布局文件.代码如下
<transition mode="out-in" name="el-fade-in-linear">
          <keep-alive :include="tagNames">
            <router-view
              v-loading="loadingFlag"
              element-loading-text="正在加载中"
              id="admin-box"
              class="admin-box"
              v-if="$route.meta.keepAlive"
            ></router-view>
          </keep-alive>
        </transition>
        <transition mode="out-in" name="el-fade-in-linear">
          <router-view
            v-loading="loadingFlag"
            element-loading-text="正在加载中"
            id="admin-box"
            class="admin-box"
            v-if="!$route.meta.keepAlive"
          ></router-view>
        </transition>
computed: {
    ...mapGetters("history", ["tagNames"]),
 },
3.在全局路由守卫中加上这段代码:(仅仅只是满足三级菜单缓存)

在这里插入图片描述

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)
            }
        }
    }
    ..........

面包屑代码

<el-breadcrumb
  class="breadcrumb"
  separator-class="el-icon-arrow-right"
>
  <el-breadcrumb-item
    :key="item.path"
    v-for="item in matchedRouter.slice(1, matchedRouter.length)"
    >{{ item }}</el-breadcrumb-item
  >
</el-breadcrumb>
watch: {
    $route(){
      let matchedRouter = JSON.parse(sessionStorage.getItem("matchedRouter"))
      this.matchedRouter = matchedRouter;
    }
  },

希望对你有帮助

  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2022-03-24 00:26:06  更:2022-03-24 00:26:40 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 4:32:36-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码