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: { + // 鑾峰彇鏈塳eep-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鏄敤鏉ヨ幏鍙栧墠缂�鐢ㄦ潵鍚庨潰姝e垯鍖归厤鐢ㄧ殑 + 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.3