旧方案存在的问题

之前在https://blog.csdn.net/weixin_35958891/article/details/102685382博客中解决了三级菜单无法缓存的问题,但是那个方案是有bug 的就是缓存只在超过20个后才会删除第一个旧的,也就是会同时存在20个页面缓存的情况,除非f5刷新要不然缓存一直都存在。

解决思路

看了大佬的博客得到启发 https://juejin.im/post/6844903649517240328,删除标签的时候将缓存删掉。TagsView.vue中删除单个、删除其他、删除全部标签分别触发方法,到AppMain.vue中去实现具体的删除逻辑。下面是vue的keep-alive.js的源码,感兴趣的可以把vue的源码拉下来看一下,

function pruneCacheEntry (cache,key,keys,current) {const cached = cache[key]if (cached && (!current || cached.tag !== current.tag)) {cached.componentInstance.$destroy()}cache[key] = nullremove(keys, key)
}

可以看到删除缓存一共分三步

1、调用destory()
2、清空cache
3、移除kes里对应的key值

代码

layout/components/AppMain.vue中

<template><section class="app-main"><transition name="fade-transform" mode="out-in"><keep-alive :max="20"><router-view :key="key" /></keep-alive></transition></section>
</template><script>
import Bus from '../bus.js'
export default {name: 'AppMain',computed: {cachedViews() {return this.$store.state.tagsView.cachedViews;},key() {return this.$route.fullPath;}},mounted() {// 关闭标签触发Bus.$on('removeCache', (name, view) => {this.removeCache(name, view);});},methods: {// 获取有keep-alive子节点的VnodegetVnode() {// 判断子集非空if (this.$children.length == 0) return false;let vnode;for (let item of this.$children) {// 如果data中有key则代表找到了keep-alive下面的子集,这个key就是router-view上的keyif (item.$vnode.data.key) {vnode = item.$vnode;break;}}return vnode ? vnode : false;},// 移除keep-alive缓存removeCache(name, view = {}) {let vnode = this.getVnode();if (!vnode) return false;let componentInstance = vnode.parent.componentInstance;// 这个key是用来获取前缀用来后面正则匹配用的let keyStart = vnode.key.split('/')[0];let thisKey = `${keyStart}${view.fullPath}`;let regKey = `${keyStart}${view.path}`;this[name]({ componentInstance, thisKey, regKey });},// 移除其他closeOthersTags({ componentInstance, thisKey }) {Object.keys(componentInstance.cache).forEach((key, index) => {if (key != thisKey) {// 1 销毁实例(这里存在多个key指向一个缓存的情况可能前面一个已经清除掉了所有要加判断)if (componentInstance.cache[key]) {componentInstance.cache[key].componentInstance.$destroy();}// 2 删除缓存delete componentInstance.cache[key];// 3 移除key中对应的keycomponentInstance.keys.splice(index, 1);}});},// 移除所有缓存closeAllTags({ componentInstance }) {// 1 销毁实例Object.keys(componentInstance.cache).forEach(key => {if (componentInstance.cache[key]) {componentInstance.cache[key].componentInstance.$destroy();}});// 2 删除缓存componentInstance.cache = {};// 3 移除key中对应的keycomponentInstance.keys = [];},// 移除单个缓存closeSelectedTag({ componentInstance, regKey }) {let reg = new RegExp(`^${regKey}`);Object.keys(componentInstance.cache).forEach((key, i) => {if (reg.test(key)) {// 1 销毁实例if (componentInstance.cache[key]) {componentInstance.cache[key].componentInstance.$destroy();}// 2 删除缓存delete componentInstance.cache[key];// 3 移除key中对应的keycomponentInstance.keys.splice(i, 1);}});}}
};
</script>

layout/components/TagsView.vue中,这里主要就是用bus触发一下方法,就不贴完整代码了,免得干扰主逻辑,不要忘了引入bus,在beforeDestory生命周期里把bus关一下

closeSelectedTag(view) {this.$store.dispatch("delView", view).then(({ visitedViews }) => {if (this.isActive(view)) {const latestView = visitedViews.slice(-1)[0];if (latestView) {this.$router.push(latestView);} else {this.$router.push("/");}}//关闭单个Bus.$emit('removeCache','closeSelectedTag',view)});},closeOthersTags() {this.$router.push(this.selectedTag);//关闭其他Bus.$emit('removeCache','closeOthersTags',this.selectedTag);this.$store.dispatch("delOthersViews", this.selectedTag).then(() => {this.moveToCurrentTag();});},closeAllTags(view) {this.$store.dispatch("delAllViews").then(({ visitedViews }) => {this.toLastView(visitedViews, view);//关闭所有Bus.$emit('removeCache','closeAllTags')});},

vue-element-admin项目采用keep-alive全缓存,删除标签移除指定的缓存相关推荐

  1. Vue Element Admin 使用mock模块模拟数据

    Mock 数据是前端开发过程中必不可少的一环,是分离前后端开发的关键链路.通过预先跟服务器端约定好的接口,模拟请求数据甚至逻辑,能够让前端开发更加独立自主,不会被服务端的开发所阻塞. vue-elem ...

  2. vue+element+admin(初始化项目)

    2022.10.17我接触到了vue+element+admin的使用,首先要安装node.jshttps://nodejs.org/zh-cn/download/.和githttps://git-s ...

  3. vue element admin登录方式切换(密码登录或短信登录)

    显示结果: 具体代码可以根据vue element admin源码进行更改,下面是页面代码 <el-form ref="loginForm" :model="log ...

  4. 后端使用SpringBoot和Jwt工具与Redis数据库+前端Vue Element Admin实现用户携带token的登录功能案例

    登录功能描述: 前端输入对应的用户信息 ,在用户输入邮箱后 点击发送按钮给邮箱发送验证码,拿取到验证填完之后,点击登录按钮给后端发送请求 ,后端接收到请求之后 ,第一步校验验证码,第二步校验用户名和密 ...

  5. Vue Element Admin 添加侧边栏以及他的页面

    1. 在 /src/views/ 下添加需要的页面 2. 配置路由器 router 中的路由表 routes,分为 constantRoutes 和 asyncRoutes. 将路由的配置信息添加进路 ...

  6. Vue Element Admin 用mock模块模拟数据

    步骤简单 一  在 src/api/charts 中添加接口 , 方法名为 getindexMock  import request from '@/utils/request'export func ...

  7. vue element admin中发送请求和设置loading效果

    需求:在表格数据加载完成前进入loading显示数据正在加载,数据加载完成后取消loading效果,axios的超时处理和异常的处理之后进行取消loading效果. 小编接下来就根据这个这个需求进行分 ...

  8. Vue+Element组件el-table添加表头全选文字

    html部分: <el-table v-if="showTable"class="inter_table":data="apiList.slic ...

  9. Vue + Element UI——侧边栏LOGO设计DEMO

    GitHub https://github.com/PanJiaChen/vue-element-admin DEMO https://panjiachen.github.io/vue-element ...

最新文章

  1. 如何从值获取C#枚举描述? [重复]
  2. Luogu P4782 【模板】2-SAT 问题(2-SAT)
  3. 局部静态变量Static详解
  4. spark中累加器的使用(转)
  5. github authentication设置里,fallback SMS number国家选项里没有中国的问题
  6. expect switch 多条件_JavaScript-流程控制语句:选择结构(if和switch)
  7. 仅剩296个免费名额,AI工程师进阶必修课今日领取
  8. Java Integer类详解
  9. NB-IoT的DRX、eDRX、PSM三个模式怎么用?
  10. 自如CEO熊林接任董事长
  11. 新版财经直播间系统 贵金属喊单直播间 视频直播室在线喊单 源码
  12. 中望3d快捷键命令大全_cad快捷键命令大全
  13. 使用LOIC 对新搭建的网站迚行DDOS攻击
  14. 计算机术语BOOTP,bootp是什么意思?
  15. (人才测评)什么是创造力?如何提高创造力?
  16. Mutual Supervision for Dense Object Detection(ICCV2021)阅读笔记
  17. 【游戏开发小技】Unity中实现Dota里的角色技能地面贴花效果(URP ShaderGraph Decal)
  18. 画油画,笔触的重要性原来体现在这里~
  19. CPU 与 GPU 渲染:如何选择及原因?
  20. Python中带“symmetric_”前缀的方法的特点

热门文章

  1. 大数据资源管理方案研究
  2. 笔记本各型号CPU性能比较
  3. 没有归属感?辛苦如牛?软件测试外包那些事,你真的了解吗?
  4. hexdump命令的使用
  5. 阿里巴巴开源项目集锦
  6. java编写监控redis集群,Redis监控方案
  7. 嵌入式新建工程步骤(STM32F103XXX)
  8. 2016级计专班编程课程主页
  9. Windows下怎样解压.tar.xz文件
  10. Word 表格填写信息(XX 证券案例)