首页 > 其他分享 >vue3 keep-alive实现tab页面缓存

vue3 keep-alive实现tab页面缓存

时间:2023-04-23 10:01:37浏览次数:48  
标签:缓存 const name componentName alive keep 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中,可根据自己项目进行相应的修改即可完成页面的缓存功能。

 

标签:缓存,const,name,componentName,alive,keep,tab,路由,页面
From: https://www.cnblogs.com/minjh/p/17345596.html

相关文章

  • sql语法错误[1093] You can't specify target table 'score' for update in FROM clau
    不能在同一张表中将查询非结果集作为更新条件执行将需要的结果集外层套一层自查询如updateaseta.num=a.num+1wherea.namein(selecta.agefromawherexx=xxx);报错[1093]Youcan'tspecifytargettable'score'forupdateinFROMclauseupdateaseta......
  • 阿里云 AIGC 白嫖 FC 搭建 stable diffusion
    下午瞎逛在V站看到阿里在做推广,正好这几天在研究stable-diffusion,就进去看了看,活动地址:https://developer.aliyun.com/topic/aigc。主要就是阿里云的FC免费提供3个月的试用(注意,只有150元额度,所以重度使用可能一会就玩没了),可以快速搭建AiGC服务。安装注意阿里云官......
  • uni-app 页面传值 tabbar切换
    场景:tabbar页面是展示一个列表,页面中有一个搜索按钮,点击按钮进入搜索页面,输入字段以后返回tabbar页面展示相应的搜索结果,切换tabbar页面后搜索条件置空 方案1:使用navigateTo跳转传值坑1:因为搜索页要跳转的是tabbar页面,不能直接使用navigateTo跳转,只能使用switchTab,但是switc......
  • lua变量、数据类型、if判断条件和数据结构table以及【lua 函数】
    一、lua变量【全局变量和局部变量和表中的域】Lua变量有三种类型:全局变量和局部变量和表中的域。▪全局变量:默认情况下,Lua中所有的变量都是全局变量。▪局部变量:使用local显式声明在函数内的变量,以及函数的参数,都是局部变量。在函数外即使用local去声明,它的作用域也是当前的整......
  • Bootstrap Table表格中存放下拉框,读取数据填充到下拉框
    初学Bootstarp,个人感觉一个功能非常强大的前端框架,由于学习的路途也不是一番风顺的,难免会遇到问题,将遇到的问题整理,可以时常看看,加深记忆。最近做表格需要在表格中加入<select>标签,将数据填充到下拉框,无奈搞了好几个小时也没有成功,最后经过请教身边的大佬,得以解决。代码如下:htt......
  • springboot+bootstraptable
    springboot+bootstraptable项目采用的是springboot+bootstraptable搭建的demo  https://blog.csdn.net/weixin_43373818/article/details/114714016基础的增删改查已经实现html页面<!DOCTYPEhtml><htmllang="zh-CN"xmlns:th="http://www.thymeleaf.org"><......
  • bootstraptable单元格可输入(输入框,下拉框)
    https://blog.csdn.net/weixin_45742032/article/details/105145655bootstraptable单元格可输入效果图效果图一(单元格中加入下拉框,这里的数据是从数据库取的) <tableid="payment_detail_table"></table>js内容vartemplateTableParams={classes:"tabletable......
  • 猛读论文6 |【CVPR 2022】Camera-Conditioned Stable Feature Generation for Isolate
    用于孤立摄像机监督行人重识别的摄像机条件稳定特征生成动机常规ReID,对于一个ID,在不同摄像头拍摄的图片上提取跨相机视图不变特征而ISCS情况下,无法做到同一个ID采集到不同摄像头图片由于跨相机样本在人体Re-ID模型训练中起着重要作用,而在ISCS设置下不存在此类配对图像,因......
  • Installation failed with message Failed to establish session
    Androidstudio的setting里面build==》关闭instantrun用Androidstudio2.3调度程序时提示“InstallationfailedwithmessageFailedtoestablishsession”错误,需要在在开发者选项里关闭MIUI优化!开启手机开发者模式,在开发者选择中打开,USB安装(允许通过USB安装应用)......
  • 获取博客园的metablogapi
    注意:metablogapi为rpc服务,详细解释如下:https://www.cnblogs.com/mq0036/p/12766789.html如何获取:首先进入:https://i.cnblogs.com/settings然后拉到最下方,复制相应的metawebolg链接生成相应的metaweblog令牌......