vue3 keep-alive实现tab页面缓存功能

 更新时间:2023年04月23日 10:10:54   作者:土豆儿哥  
如何在我们切换tab标签的时候,缓存标签最后操作的内容,简单来说就是每个标签页中设置的比如搜索条件及结果、分页、新增、编辑等数据在切换回来的时候还能保持原样,这篇文章介绍vue3 keep-alive实现tab页面缓存功能,感兴趣的朋友一起看看吧

先上图

 如何在我们切换tab标签的时候,缓存标签最后操作的内容,简单来说就是每个标签页中设置的比如搜索条件及结果、分页、新增、编辑等数据在切换回来的时候还能保持原样。

看看keep-alive是如何实现该功能的。

首先我们要了解keep-alive的基本使用。

具体介绍请查看官方文档(https://cn.vuejs.org/guide/built-ins/keep-alive.html#basic-usage

这里有几个问题需要注意一下:

1、需要考虑页面共用的问题,如“新增/编辑”不是弹窗而是跳转页面,打开新增页面返回列表点击编辑页面,如果不做缓存清理跳转的将还是新增页面。

2、当页面关闭时再次打开如何清理之前的缓存。

废话不多说,上代码:

先创建一个处理缓存路由的文件 useRouteCache.ts

import { ref, nextTick, watch } from 'vue'
import store from '../store'

const caches = ref<string[]>([])
let collect = false

export default function useRouteCache() {
  const route = store.state

  // 收集当前路由相关的缓存
  function collectRouteCaches() {
    route.visitedView.forEach((routeMatch) => {
      const componentName: any = routeMatch?.name

      // 已打开的路由组件添加到缓存
      if (!componentName) {
        return
      }
      addCache(componentName)
    })
  }

  // 收集缓存(通过监听)
  function collectCaches() {
    if (collect) {
      return
    }
    collect = true
    watch(() => route.path, collectRouteCaches, {
      immediate: true
    })
  }

  // 添加缓存的路由组件
  function addCache(componentName: string | string[]) {
    if (Array.isArray(componentName)) {
      componentName.forEach(addCache)
      return
    }

    if (!componentName || caches.value.includes(componentName)) return
    caches.value.push(componentName)
  }

  // 移除缓存的路由组件
  function removeCache(componentName: string | string[]) {
    if (Array.isArray(componentName)) {
      componentName.forEach(removeCache)
      return
    }

    const index = caches.value.indexOf(componentName)
    //
    if (index > -1) {
      return caches.value.splice(index, 1)
    }
  }

  // 移除缓存的路由组件的实例
  async function removeCacheEntry(componentName: string) {
    if (removeCache(componentName)) {
      await nextTick()
      addCache(componentName)
    }
  }

  return {
    collectCaches,
    caches,
    addCache,
    removeCache,
    removeCacheEntry
  }
}

然后在动态路由页面进行引入:

<template>
  <router-view v-slot="{ Component }">
    <keep-alive :include="caches" :max="10">
      <component :is="Component" />
    </keep-alive>
  </router-view>
</template>

<script lang="ts">
import { defineComponent, onMounted } from 'vue'
import useRouteCache from './hooks/useRouteCache'
export default defineComponent({
  name: 'Main',
  setup() {
    const { caches } = useRouteCache()
    // 收集已打开路由tabs的缓存
    const { collectCaches } = useRouteCache()
    onMounted(collectCaches)

    return {
      caches
    }
  }
})
</script>

这里做的是菜单可配置的,也就是从后台读取的。如果是本地路由更简单,只需要在路由对象meta中加入keep属性,true表示当前路由需要缓存,false则不需要缓存

之前说的两个问题,这里说下解决办法:

在我们的tabbar(也就是tab标签)组件中,监听路由变化时进行判断,新增页面是不带参数的,编辑页带参数,通过这个进行缓存清除

watch: {
      const findItem: any = this.state.visitedView.find(
        (it) => it.name === newVal.name
      )
      if (
        findItem &&
        newVal.name === findItem?.name &&
        newVal.fullPath !== findItem?.fullPath
      ) {
        // 同一个路由,但是新旧路径不同时,需要清除路由缓存。例如route.path配置为 '/detail/:id'时路径会不同
        removeCacheEntry(newVal.name)
      } else {
        addCache(newVal.name)
      }
    }
  }

还有就是当我们关闭tab页时清除路由缓存

removeTab(name) {
      const findItem: any = this.state.visitedView.find(
        (it) => it.fullPath === name
      )
      if (findItem) {
        store.removeVisitedView(findItem).then((_) => {
          if (this.currentTab === name) {
            this.currentTab =
              this.state.visitedView[this.state.visitedView.length - 1].fullPath
            this.$router.push(this.currentTab)
          }
        })
        // 同时移除tab缓存
        removeCache(findItem.name || '')
      }
    }

这里的路由都是保存在store中,可根据自己项目进行相应的修改即可完成页面的缓存功能。

到此这篇关于vue3 keep-alive实现tab页面缓存的文章就介绍到这了,更多相关vue3 keep-alive页面缓存内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • VUE项目实现全屏显示功能之screenfull用法

    VUE项目实现全屏显示功能之screenfull用法

    这篇文章主要介绍了VUE项目实现全屏显示功能之screenfull用法,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-01-01
  • Vue自定义指令实现卡片翻转功能

    Vue自定义指令实现卡片翻转功能

    这篇文章主要给大家介绍了Vue自定义指令实现卡片翻转功能的代码示例,文章通过代码示例讲解的非常详细,对大家的学习或工作有一定的参帮助,需要的朋友可以参考下
    2023-11-11
  • Vue3中使用Pinia的方法详细介绍

    Vue3中使用Pinia的方法详细介绍

    这篇文章主要给大家介绍了关于Vue3中使用Pinia的相关资料,pinia是一个用于vue的状态管理库,类似于vuex,是vue的另一种状态管理工具,文中介绍的非常详细,需要的朋友可以参考下
    2024-01-01
  • 干货!教大家如何选择Vue和React

    干货!教大家如何选择Vue和React

    Vue和React之间如何选择,这篇文章主要为大家详细介绍了Vue和React两者之间的相同之处,教大家该如何进行选择,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-03-03
  • 关于配置babel-plugin-import报错的坑及解决

    关于配置babel-plugin-import报错的坑及解决

    这篇文章主要介绍了关于配置babel-plugin-import报错的坑及解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-12-12
  • vue实现excel文件导入导出操作示例

    vue实现excel文件导入导出操作示例

    这篇文章主要为大家介绍了vue实现excel文件的导入导出实现示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-07-07
  • Vue数据变化后页面更新详细介绍

    Vue数据变化后页面更新详细介绍

    这篇文章主要介绍了Vue在数据发生变化后是如何更新页面的,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习吧
    2022-10-10
  • vue自动添加浏览器兼容前后缀操作

    vue自动添加浏览器兼容前后缀操作

    这篇文章主要介绍了vue自动添加浏览器兼容前后缀操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-08-08
  • Template ref在Vue3中的实现原理详解

    Template ref在Vue3中的实现原理详解

    这篇文章主要为大家介绍了Template ref在Vue3中的实现原理示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-07-07
  • Vue组件实现原理详细分析

    Vue组件实现原理详细分析

    这篇文章主要介绍了Vue组件基础操作,组件是vue.js最强大的功能之一,而组件实例的作用域是相互独立的,这就意味着不同组件之间的数据无法相互进行直接的引用
    2023-01-01

最新评论