修复三级菜单之间切换页面无法缓存的问题
This commit is contained in:
		| @@ -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 @@ export default { | ||||
|   overflow: hidden; | ||||
| } | ||||
|  | ||||
| .fixed-header+.app-main { | ||||
| .fixed-header + .app-main { | ||||
|   padding-top: 50px; | ||||
| } | ||||
|  | ||||
| @@ -41,7 +144,7 @@ export default { | ||||
|     min-height: calc(100vh - 84px); | ||||
|   } | ||||
|  | ||||
|   .fixed-header+.app-main { | ||||
|   .fixed-header + .app-main { | ||||
|     padding-top: 84px; | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -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 @@ export default { | ||||
|           }) | ||||
|         }) | ||||
|       }) | ||||
|       Global.$emit("removeCache", "refreshSelectedTag", this.selectedTag); | ||||
|     }, | ||||
|     closeSelectedTag(view) { | ||||
|       this.$store.dispatch('tagsView/delView', view).then(({ visitedViews }) => { | ||||
| @@ -151,12 +153,14 @@ export default { | ||||
|           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 @@ export default { | ||||
|         } | ||||
|         this.toLastView(visitedViews, view) | ||||
|       }) | ||||
|       Global.$emit("removeCache", "closeAllTags"); | ||||
|     }, | ||||
|     toLastView(visitedViews, view) { | ||||
|       const latestView = visitedViews.slice(-1)[0] | ||||
|   | ||||
							
								
								
									
										3
									
								
								ruoyi-ui/src/layout/components/global.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								ruoyi-ui/src/layout/components/global.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | ||||
| import Vue from 'vue' | ||||
| const global = new Vue() | ||||
| export default global | ||||
		Reference in New Issue
	
	Block a user