首页 > 其他分享 >vue3中tab详情页多开keepalive根据key去动态缓存与清除缓存

vue3中tab详情页多开keepalive根据key去动态缓存与清除缓存

时间:2022-10-11 14:14:37浏览次数:98  
标签:__ 缓存 name state 详情页 key exclude true

一. 场景
由于存在tab栏,当从查询页面点击列表进入详情时,需求是详情页都会新开一个tab,并缓存,
tab中的切换不会重新加载详情页数据,但是关闭一个详情tab,再次从查询页点击这条详情数据时,是需要重新加载的。

二. 问题产生
这就导致了一个问题,由于keepalive使用include或者exclude去动态添加取消缓存时,只会根据组件的name去进行缓存,当删除一个
详情页的缓存,其他打开的详情页也会被清除。如果不删除,点击刚才那条列表数据还是取的缓存中的值。

三. 思考
那是不是可以从根本上改变keepalive的include,exclude机制,将key作为条件去缓存而不仅限于name。
顺着这个思路,找到了一个控件:

https://github.com/meadmin-cn/meadmin-template/tree/main/src/components/meKeepAlive

这里通过修改keepalive的源码,集成了使用key的方式去缓存。且用includeKey和excludeKey代表缓存和不缓存的key。(原有的用include和exclude缓存name的也可以用)

四. 使用
1.将meKeepAlive文件下载下来,放入自己的项目中。

2.放入自己文件夹中后,会发现有一些全局变量是没有定义的,需要配置一下。

在webpack.config.js的plugins中定义:
new webpack.DefinePlugin({
      __SSR__: `true`,
      __DEV__: !isBuild ? `true` : `false`,
      __COMPAT__: `false`,
      __FEATURE_SUSPENSE__: `true`,
      __FEATURE_PROD_DEVTOOLS__: `false`,
})

在.eslintrc.js中定义:
globals:{
    '__DEV__': true,
    '__SSR__': true,
    '__FEATURE_PROD_DEVTOOLS__': true,
    '__FEATURE_SUSPENSE__': true,
    '__COMPAT__': true,
  },

在外部index.d.ts文件中声明:
declare let __SSR__: boolean;
declare let __DEV__: boolean;
declare let __FEATURE_PROD_DEVTOOLS__: boolean;
declare let __FEATURE_SUSPENSE__: boolean;
declare let __COMPAT__: boolean;

上述还有疑问也可以看看链接中源码的定义,是在vite中做了对应的处理。 还会有一些错误,是说某个key不在对象定义的类型中,这时就将那个对象类型声明为any就好。 如:本来会报一个ssContent不在vnode,将(vnode:any)即可 function getInnerChild(vnode: any) { return vnode.shapeFlag & ShapeFlags.SUSPENSE ? vnode.ssContent! : vnode; }

此时就能编译通过了。

3.引入组件并在路由中使用

           <router-view>
              {({ Component }: { Component: any }) => {
                return (
                  <meKeepAlive excludeKey={this.store.exclude}>
                    <Component key={this.$route.fullPath}></Component>
                  </meKeepAlive>
                );
              }}
            </router-view>
                              

4.此处我是用的excludeKey去动态实现缓存的,且放在状态管理中统一管理:

    state: () => {
      return {
        exclude: []
      }
    },
    mutations: {
      setExclude(state, name) {
        if (state.exclude.length == 0) {
          state.exclude.push(name)
        } else {
          var flag = false
          for (let i = 0; i < state.exclude.length; i++) {
            if (name == state.exclude[i]) {
              flag = true
            }
          }
          if (!flag) {
            state.exclude.push(name)
          }
        }
      },
      deleteExclude(state, name) {
        if (state.exclude.length != 0) {
          var flag = false
          var index = 0
          for (let i = 0; i < state.exclude.length; i++) {
            if (name == state.exclude[i]) {
              flag = true
              index = i
            }
          }
          if (flag) {
            state.exclude.splice(index, 1)
          }
        }
      },
    },
    actions: {
      async setExclude(context, name) {
        context.commit('setExclude', name);
      },
      async deleteExclude(context, name) {
        context.commit('deleteExclude', name);
      },
    }

5.触发缓存与不缓存时机,当tab页关闭的时候,添加到不缓存;当路由打开的时候,删除不缓存;
这一步可以都在你tab的组件中去做。

如下是在tab组件中:

tab关闭的回调中调用将此标签的fullPath添加到不缓存:
GlobalStore.dispatch(`setExclude`, fullPath);

监听路由变换,路由进入的时候删除不缓存,也就是将进入时的fullPath缓存:
watch: {
    $route(to, from) {
      if (to.fullPath === from.fullPath) {
        return;
      }
      GlobalStore.dispatch(`deleteExclude`, to.fullPath);
    },
  },

五. 注意
以上所有的fullPath都是定义菜单信息的时候自定义的变量,上面的key绑定你自定义的变量就行。

这样就能实现效果了(^-^)V

标签:__,缓存,name,state,详情页,key,exclude,true
From: https://www.cnblogs.com/xinyouhunran/p/16779002.html

相关文章

  • key_t IPC键和ftok函数详解和剖析
    统建立IPC通讯(如消息队列、共享内存时)必须指定一个ID值。通常情况下,该id值通过ftok函数得到。ftok原型如下:key_tftok(char*fname,intid)fname就时你指定的文件名(......
  • redis本地缓存
    我不想带给你负面情绪,但又想让你知道我的不开心。为了系统性能的提升,一般会将部分数据放入缓存中,加快访问速度。而db承担数据罗盘工作。哪些数据适合放在缓存及时性......
  • 什么是缓存雪崩?服务器雪崩的场景与解决方案
    目录什么是应用服务雪崩雪崩效应产生的几种场景缓存雪崩的解决方案雪崩的整体解决方案熔断设计隔离设计超时机制设计如何提前发现雪崩 什么是应用服务雪......
  • HugeGraph创建propertyKey出现The name of property key can't be null
    1、发生错误场景(开发环境)importjava.io.IOException;importjava.util.Iterator;importjava.util.List;importjava.util.Map;importcom.baidu.hugegraph.driver......
  • autohotkey chrome 查词 截图 收集单词
    chrome查词截图收集单词#IfWinActiveahk_exemsedge.exe{^!`::screen();有道查词`::searchWord1();收集单词!`::collectWord()}#IfWi......
  • autohotkey 视频遥控器
    GroupAddremoteKey,ahk_exemsedge.exeGroupAddremoteKey,ahk_exechrome.exeGroupAddremoteKey,ahk_exe哔哩哔哩.exeGroupAddremoteKey,ahk_exebdcam.exe......
  • 浏览器缓存
    1.由后端通过response响应头设置的缓存1.1强缓存1.1.1什么是强缓存所谓的强缓存是指将由后台返回过来的文件存储到本地,当再次请求相同文件时,不用再去向服务器......
  • 【SpringBoot】解决redis 查找/删除缓存失败问题
     使用StringRedisTemplate.delete(key) 删除缓存数据失败,原因是序列化问题导致。 需要把key和hash都使用String的序列化方式 解决方法:创建一个新的配置类:@Con......
  • qt 回车事件之Qt::Key_Return与Qt::Key_Enter
    这两个都得包含限制!缺一个不行。Key_Enter是小键盘的确认键,Key_Return是大键盘的回车键。voidWidget::keyPressEvent(QKeyEvent*ev){if(ev->key()==Qt::Key_Enter|......
  • Springboot整合缓存
    一、缓存的引入一个应用主要瓶颈在于数据库的IO,大家都知道内存的速度是远远快于硬盘的速度(即使固态硬盘与内容也无法比拟)。应用之中经常会遇到返回相同的数据(数据字典,行政......