当前位置: 首页 > article >正文

【vue】聊一聊嵌套路由使用keep-alive缓存的实现

背景

大家应该都写过类似下图布局的页面,一个顶部导航、一个侧边菜单和一个主要内容区域。其中只有主要内容区域是变化。在这个基础上实现缓存大家应该都有经历过。只要在router-view上使用keep-alive标签就可以轻松实现缓存。但是在多层嵌套的router-view中,只能缓存到该层下的router-view。针对上面的情况下面聊聊我的实现。(以下内容都是基于Vue3 + pinia 实现)
在这里插入图片描述

路由层级扁平化

搜索网上的方案大部分都是说将路由层级扁平化,直白点就是在路由守卫中将route对象的matched属性将使用到router-view的组件进行删除,将路由层级提升,从而实现缓存的目的。这种方案可行,但是不能适用于所有情况。如果路由组件中存在布局(如下图),那该方案会将会丢失这部分(红色框内)内容。
在这里插入图片描述

所有router-view都使用keep-alive(推荐)

既然keep-alive无法多层嵌套缓存,那我们可以换个思路,将每个router-view都使用keep-alive,通过include属性来判断组件是否需要进行缓存。

重新封装router-view组件

我们必然不会只在一处使用router-view,那我们就需要对router-view组件进行二次封装。举例代码如下

<script setup>
import { computed } from 'vue'
import { useRouteCacheStore } from '@/stores/modules/route-cache'

defineProps({
  keepalive: {
    type: Boolean,
    default: () => false
  }
})

const routeCacheStore = useRouteCacheStore()

const keepalives = computed(() => routeCacheStore.keepalives)

</script>

<template>
  <router-view v-slot="{ Component }">
    <keep-alive :include="keepalives" v-if="keepalive">
      <component :is="Component" />
    </keep-alive>
    <component :is="Component" v-else />
  </router-view>
</template>

代码中的keepalives就是需要缓存组件名称的数组,一般情况下我们都是放在pinia或者vuex中。

import { defineStore } from 'pinia'

export const useRouteCacheStore = defineStore('routeCache', {
  state: () => ({
    keepalives: ['One', 'Two', 'Three', 'Four', 'Five', 'Six', 'Seven', 'Eight'],
  })
})

路由层级

在这里插入图片描述

如上图:路由一、二、三为同级路由,其中路由三为使用router-view的组件。路由三下的路由四、五、六也为同级路由,其中路由六为使用router-view的组件。路由六下的路由七、八也为同级路由。
嵌套路由层级代码如下

{
  path: '/route-cache',
  name: 'routeCache',
  redirect: { name: 'routeCacheOne' },
  component: () => import('../views/route-cache/index.vue'),
  children: [
    {
      path: '/one',
      name: 'routeCacheOne',
      component: () => import('../views/route-cache/views/one/index.vue')
    },
    {
      path: '/two',
      name: 'routeCacheTwo',
      component: () => import('../views/route-cache/views/two/index.vue')
    },
    {
      path: '/three',
      name: 'routeCacheThree',
      redirect: { name: 'routeCacheFour' },
      component: () => import('../views/route-cache/views/three/index.vue'),
      children: [
        {
          path: '/four',
          name: 'routeCacheFour',
          component: () => import('../views/route-cache/views/four/index.vue')
        },
        {
          path: '/five',
          name: 'routeCacheFive',
          component: () => import('../views/route-cache/views/five/index.vue')
        },
        {
          path: '/six',
          name: 'routeCacheSix',
          redirect: { name: 'routeCacheSeven' },
          component: () => import('../views/route-cache/views/six/index.vue'),
          children: [
            {
              path: '/seven',
              name: 'routeCacheSeven',
              component: () => import('../views/route-cache/views/Seven/index.vue')
            },
            {
              path: '/eight',
              name: 'routeCacheEight',
              component: () => import('../views/route-cache/views/eight/index.vue')
            },
          ]
        },
      ]
    },
  ]
}

注意

如上图的结构,如果所有组件都需要缓存那keepalives数组应该等于[‘One’, ‘Two’, ‘Three’, ‘Four’, ‘Five’, ‘Six’, ‘Seven’, ‘Eight’], 而不是[‘One’, ‘Two’, ‘Four’, ‘Five’, ‘Seven’, ‘Eight’]。简单的说就是使用router-view的组件(即路由三、路由六)也需要给组件命名并记录到keepalives数组中。如果不这么做的话会导致出现部分情况不缓存:
在这里插入图片描述

完整演示

在这里插入图片描述

以上就是本次分享的内容,附上源码。

感谢看官看到这里,如果觉得文章不错的话,可以给小生的几个开源项目点个Star⭐!

  • 基于 Vue3 + Element-plus 管理后台基础功能框架
    • 预览:http://admin.gumingchen.icu
    • Github:https://github.com/gmingchen/agile-admin
    • Gitee:https://gitee.com/shychen/agile-admin
    • 基础版后端:https://github.com/gmingchen/java-spring-boot-admin
    • 文档:http://admin.gumingchen.icu/doc/
  • 基于 Vue3 + Element-plus + websocket 即时聊天系统
    • 预览:https://chatterbox.gumingchen.icu/
    • 代码:https://github.com/gmingchen/chatterbox
  • 基于 node 开发的后端服务:https://github.com/gmingchen/node-server

http://www.kler.cn/a/614805.html

相关文章:

  • 面向服务架构(SOA)及ESB的作用与特点
  • 2023第十四届蓝桥杯大赛软件赛国赛C/C++ 大学 B 组(真题题解)(C++/Java题解)
  • 算法-前缀和与差分
  • FGSM对抗样本生成算法实现(pytorch版)
  • AI助力高效办公:如何利用AI制作PPT提升工作效率
  • 结构化分析方法 数据流图详解
  • 工业控制系统安全:从漏洞到防线,Python如何成为你的护卫者
  • 图论 岛屿问题 ACM 模式 JS
  • 怎么搭建区块链服务私有云平台
  • C++实现布隆过滤器
  • 创意 Python 爱心代码分享
  • Python常用爬虫库介绍
  • vue3+element plus +el-tree-v2实现树形单选
  • presto任务优化参数
  • Uniapp微信开发树形选择组件
  • LeetCode 热题 100_杨辉三角(82_118_简单_C++)(动态规划)
  • Tof 深度相机原理
  • 0基础STM32之滤波函数(卡尔曼滤波)
  • 抽象的算法0.1.3.1版本
  • 算法训练营第二十八天 | 动态规划(一)