From c666faed6691bf51918195484f22354ebcf86b8d Mon Sep 17 00:00:00 2001
From: RuoYi <yzz_ivy@163.com>
Date: 星期六, 28 十一月 2020 20:31:45 +0800
Subject: [PATCH] 修复三级菜单之间切换页面无法缓存的问题
---
ruoyi-ui/src/layout/components/global.js | 3 +
ruoyi-ui/src/layout/components/AppMain.vue | 121 +++++++++++++++++++++++++++++++++++++---
ruoyi-ui/src/layout/components/TagsView/index.vue | 5 +
3 files changed, 120 insertions(+), 9 deletions(-)
diff --git a/ruoyi-ui/src/layout/components/AppMain.vue b/ruoyi-ui/src/layout/components/AppMain.vue
index 423437b..8da5714 100644
--- a/ruoyi-ui/src/layout/components/AppMain.vue
+++ b/ruoyi-ui/src/layout/components/AppMain.vue
@@ -1,7 +1,8 @@
+<!-- @author ruoyi 20201128 支持三级以上菜单缓存 -->
<template>
<section class="app-main">
<transition name="fade-transform" mode="out-in">
- <keep-alive :include="cachedViews">
+ <keep-alive :max="20" :exclude="notCacheName">
<router-view :key="key" />
</keep-alive>
</transition>
@@ -9,17 +10,119 @@
</template>
<script>
+import Global from "@/layout/components/global.js";
+
export default {
name: 'AppMain',
computed: {
- cachedViews() {
- return this.$store.state.tagsView.cachedViews
+ notCacheName() {
+ var visitedViews = this.$store.state.tagsView.visitedViews;
+ var noCacheViews = [];
+ Object.keys(visitedViews).some((index) => {
+ if (visitedViews[index].meta.noCache) {
+ noCacheViews.push(visitedViews[index].name);
+ }
+ });
+ return noCacheViews;
},
key() {
- return this.$route.path
- }
- }
-}
+ return this.$route.path;
+ },
+ },
+ mounted() {
+ // 关闭标签触发
+ Global.$on("removeCache", (name, view) => {
+ this.removeCache(name, view);
+ });
+ },
+ methods: {
+ // 获取有keep-alive子节点的Vnode
+ getVnode() {
+ // 判断子集非空
+ if (this.$children.length == 0) return false;
+ let vnode;
+ for (let item of this.$children) {
+ // 如果data中有key则代表找到了keep-alive下面的子集,这个key就是router-view上的key
+ if (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) {
+ // 销毁实例(这里存在多个key指向一个缓存的情况可能前面一个已经清除掉了所有要加判断)
+ if (componentInstance.cache[key]) {
+ componentInstance.cache[key].componentInstance.$destroy();
+ }
+ // 删除缓存
+ delete componentInstance.cache[key];
+ // 移除key中对应的key
+ componentInstance.keys.splice(index, 1);
+ }
+ });
+ },
+ // 移除所有缓存
+ closeAllTags({ componentInstance }) {
+ // 销毁实例
+ Object.keys(componentInstance.cache).forEach((key) => {
+ if (componentInstance.cache[key]) {
+ componentInstance.cache[key].componentInstance.$destroy();
+ }
+ });
+ // 删除缓存
+ componentInstance.cache = {};
+ // 移除key中对应的key
+ componentInstance.keys = [];
+ },
+ // 移除单个缓存
+ closeSelectedTag({ componentInstance, regKey }) {
+ let reg = new RegExp(`^${regKey}`);
+ Object.keys(componentInstance.cache).forEach((key, i) => {
+ if (reg.test(key)) {
+ // 销毁实例
+ if (componentInstance.cache[key]) {
+ componentInstance.cache[key].componentInstance.$destroy();
+ }
+ // 删除缓存
+ delete componentInstance.cache[key];
+ // 移除key中对应的key
+ componentInstance.keys.splice(i, 1);
+ }
+ });
+ },
+ // 刷新单个缓存
+ refreshSelectedTag({ componentInstance, thisKey }) {
+ Object.keys(componentInstance.cache).forEach((key, index) => {
+ if (null != thisKey && key.replace("/redirect", "") == thisKey) {
+ // 1 销毁实例(这里存在多个key指向一个缓存的情况可能前面一个已经清除掉了所有要加判断)
+ if (componentInstance.cache[key]) {
+ componentInstance.cache[key].componentInstance.$destroy();
+ }
+ // 2 删除缓存
+ delete componentInstance.cache[key];
+ // 3 移除key中对应的key
+ componentInstance.keys.splice(index, 1);
+ }
+ });
+ },
+ },
+};
</script>
<style lang="scss" scoped>
@@ -31,7 +134,7 @@
overflow: hidden;
}
-.fixed-header+.app-main {
+.fixed-header + .app-main {
padding-top: 50px;
}
@@ -41,7 +144,7 @@
min-height: calc(100vh - 84px);
}
- .fixed-header+.app-main {
+ .fixed-header + .app-main {
padding-top: 84px;
}
}
diff --git a/ruoyi-ui/src/layout/components/TagsView/index.vue b/ruoyi-ui/src/layout/components/TagsView/index.vue
index dce967c..23eb8f0 100644
--- a/ruoyi-ui/src/layout/components/TagsView/index.vue
+++ b/ruoyi-ui/src/layout/components/TagsView/index.vue
@@ -29,6 +29,7 @@
<script>
import ScrollPane from './ScrollPane'
import path from 'path'
+import Global from "@/layout/components/global.js";
export default {
components: { ScrollPane },
@@ -144,6 +145,7 @@
})
})
})
+ Global.$emit("removeCache", "refreshSelectedTag", this.selectedTag);
},
closeSelectedTag(view) {
this.$store.dispatch('tagsView/delView', view).then(({ visitedViews }) => {
@@ -151,12 +153,14 @@
this.toLastView(visitedViews, view)
}
})
+ Global.$emit("removeCache", "closeSelectedTag", view);
},
closeOthersTags() {
this.$router.push(this.selectedTag)
this.$store.dispatch('tagsView/delOthersViews', this.selectedTag).then(() => {
this.moveToCurrentTag()
})
+ Global.$emit("removeCache", "closeOthersTags", this.selectedTag);
},
closeAllTags(view) {
this.$store.dispatch('tagsView/delAllViews').then(({ visitedViews }) => {
@@ -165,6 +169,7 @@
}
this.toLastView(visitedViews, view)
})
+ Global.$emit("removeCache", "closeAllTags");
},
toLastView(visitedViews, view) {
const latestView = visitedViews.slice(-1)[0]
diff --git a/ruoyi-ui/src/layout/components/global.js b/ruoyi-ui/src/layout/components/global.js
new file mode 100644
index 0000000..5d2b5b3
--- /dev/null
+++ b/ruoyi-ui/src/layout/components/global.js
@@ -0,0 +1,3 @@
+import Vue from 'vue'
+const global = new Vue()
+export default global
--
Gitblit v1.9.2