fix: solve the cache problem in multi tabs mode; 🐛

修复: 解决多页签模式下的内存泄露问题;
This commit is contained in:
iczer 2020-07-10 21:48:29 +08:00
parent 107e08c08e
commit 255f68709e
7 changed files with 63 additions and 32 deletions

View File

@ -1,6 +1,6 @@
<template> <template>
<page-toggle-transition :disabled="animate.disabled" :animate="animate.name" :direction="animate.direction"> <page-toggle-transition :disabled="animate.disabled" :animate="animate.name" :direction="animate.direction">
<keep-alive v-if="multiPage"> <keep-alive :exclude="dustbins" v-if="multiPage">
<router-view /> <router-view />
</keep-alive> </keep-alive>
<router-view v-else /> <router-view v-else />
@ -15,7 +15,7 @@ export default {
name: 'BlankView', name: 'BlankView',
components: {PageToggleTransition}, components: {PageToggleTransition},
computed: { computed: {
...mapState('setting', ['multiPage', 'animate']) ...mapState('setting', ['multiPage', 'animate', 'dustbins'])
} }
} }
</script> </script>

View File

@ -4,7 +4,7 @@
<img :src="extraImage"/> <img :src="extraImage"/>
</div> </div>
<page-toggle-transition :disabled="animate.disabled" :animate="animate.name" :direction="animate.direction"> <page-toggle-transition :disabled="animate.disabled" :animate="animate.name" :direction="animate.direction">
<keep-alive v-if="multiPage"> <keep-alive :exclude="dustbins" v-if="multiPage">
<router-view ref="page" /> <router-view ref="page" />
</keep-alive> </keep-alive>
<router-view ref="page" v-else /> <router-view ref="page" v-else />
@ -26,7 +26,7 @@ export default {
} }
}, },
computed: { computed: {
...mapState('setting', ['isMobile', 'multiPage', 'animate', 'routesI18n']), ...mapState('setting', ['isMobile', 'multiPage', 'animate', 'routesI18n', 'dustbins']),
desc() { desc() {
return this.page.desc return this.page.desc
}, },

View File

@ -16,7 +16,7 @@
</a-tabs> </a-tabs>
<div class="tabs-view-content"> <div class="tabs-view-content">
<page-toggle-transition :disabled="animate.disabled" :animate="animate.name" :direction="animate.direction"> <page-toggle-transition :disabled="animate.disabled" :animate="animate.name" :direction="animate.direction">
<keep-alive v-if="multiPage"> <keep-alive :exclude="dustbins" v-if="multiPage">
<router-view /> <router-view />
</keep-alive> </keep-alive>
<router-view v-else /> <router-view v-else />
@ -29,7 +29,7 @@
import AdminLayout from './AdminLayout' import AdminLayout from './AdminLayout'
import Contextmenu from '../components/menu/Contextmenu' import Contextmenu from '../components/menu/Contextmenu'
import PageToggleTransition from '../components/transition/PageToggleTransition' import PageToggleTransition from '../components/transition/PageToggleTransition'
import {mapState} from 'vuex' import {mapState, mapMutations} from 'vuex'
export default { export default {
name: 'TabsView', name: 'TabsView',
@ -37,7 +37,6 @@ export default {
data () { data () {
return { return {
pageList: [], pageList: [],
linkList: [],
activePage: '', activePage: '',
menuVisible: false, menuVisible: false,
menuItemList: [ menuItemList: [
@ -48,31 +47,25 @@ export default {
} }
}, },
computed: { computed: {
...mapState('setting', ['multiPage', 'animate', 'layout']) ...mapState('setting', ['multiPage', 'animate', 'layout', 'dustbins'])
}, },
created () { created () {
const route = this.$route const route = this.$route
this.pageList.push(route) this.pageList.push(route)
this.linkList.push(route.fullPath)
this.activePage = route.fullPath this.activePage = route.fullPath
}, },
watch: { watch: {
'$route': function (newRoute) { '$route': function (newRoute) {
this.activePage = newRoute.fullPath this.activePage = newRoute.fullPath
this.putCache(newRoute)
if (!this.multiPage) { if (!this.multiPage) {
this.linkList = [newRoute.fullPath]
this.pageList = [newRoute] this.pageList = [newRoute]
} else if (this.linkList.indexOf(newRoute.fullPath) == -1) { } else if (this.pageList.findIndex(item => item.fullPath == newRoute.fullPath) == -1) {
this.linkList.push(newRoute.fullPath)
this.pageList.push(newRoute) this.pageList.push(newRoute)
} }
}, },
'activePage': function () {
// this.$router.push(key)
},
'multiPage': function (newVal) { 'multiPage': function (newVal) {
if (!newVal) { if (!newVal) {
this.linkList = [this.$route.fullPath]
this.pageList = [this.$route] this.pageList = [this.$route]
} }
} }
@ -90,12 +83,13 @@ export default {
this.$message.warning('这是最后一页,不能再关闭了啦') this.$message.warning('这是最后一页,不能再关闭了啦')
return return
} }
let index = this.linkList.indexOf(key) let index = this.pageList.findIndex(item => item.fullPath == key)
let pageRoute = this.pageList[index]
this.clearCache(pageRoute)
this.pageList = this.pageList.filter(item => item.fullPath !== key) this.pageList = this.pageList.filter(item => item.fullPath !== key)
this.linkList = this.linkList.filter(item => item !== key)
if (key == this.activePage) { if (key == this.activePage) {
index = index >= this.linkList.length ? this.linkList.length - 1 : index index = index >= this.pageList.length ? this.pageList.length - 1 : index
this.activePage = this.linkList[index] this.activePage = this.pageList[index].fullPath
this.$router.push(this.activePage) this.$router.push(this.activePage)
} }
}, },
@ -140,29 +134,59 @@ export default {
} }
}, },
closeOthers (pageKey) { closeOthers (pageKey) {
let index = this.linkList.indexOf(pageKey) const index = this.pageList.findIndex(item => item.fullPath == pageKey)
this.linkList = this.linkList.slice(index, index + 1) //
this.pageList.forEach(item => {
if (item.fullPath != pageKey){
this.clearCache(item)
}
})
this.pageList = this.pageList.slice(index, index + 1) this.pageList = this.pageList.slice(index, index + 1)
this.activePage = this.linkList[0] this.activePage = this.pageList[0].fullPath
this.$router.push(this.activePage)
}, },
closeLeft (pageKey) { closeLeft (pageKey) {
let index = this.linkList.indexOf(pageKey) const index = this.pageList.findIndex(item => item.fullPath == pageKey)
this.linkList = this.linkList.slice(index) //
this.pageList.forEach((item, i) => {
if (i < index) {
this.clearCache(item)
}
})
this.pageList = this.pageList.slice(index) this.pageList = this.pageList.slice(index)
if (this.linkList.indexOf(this.activePage) == -1) { if (this.pageList.findIndex(item => item.fullPath == this.activePage) == -1) {
this.activePage = this.linkList[0] this.activePage = this.pageList[0].fullPath
this.$router.push(this.activePage) this.$router.push(this.activePage)
} }
}, },
closeRight (pageKey) { closeRight (pageKey) {
let index = this.linkList.indexOf(pageKey) const index = this.pageList.findIndex(item => item.fullPath == pageKey)
this.linkList = this.linkList.slice(0, index + 1) //
this.pageList.forEach((item, i) => {
if (i > index) {
this.clearCache(item)
}
})
this.pageList = this.pageList.slice(0, index + 1) this.pageList = this.pageList.slice(0, index + 1)
if (this.linkList.indexOf(this.activePage) == -1) { if (this.pageList.findIndex(item => item.fullPath == this.activePage) == -1) {
this.activePage = this.linkList[this.linkList.length - 1] this.activePage = this.pageList[this.pageList.length - 1].fullPath
this.$router.push(this.activePage) this.$router.push(this.activePage)
} }
} },
clearCache(route) {
const componentName = route.matched.slice(-1)[0].components.default.name
if (this.dustbins.findIndex(item => item == componentName) == -1) {
this.setDustbins(this.dustbins.concat(componentName))
}
},
putCache(route) {
const componentName = route.matched.slice(-1)[0].components.default.name
if (this.dustbins.findIndex(item => item == componentName) != -1) {
this.setDustbins(this.dustbins.filter(item => item != componentName))
}
},
...mapMutations('setting', ['setDustbins'])
} }
} }
</script> </script>

View File

@ -6,6 +6,7 @@
import ExceptionPage from '@/components/exception/ExceptionPage' import ExceptionPage from '@/components/exception/ExceptionPage'
import {mapState} from 'vuex' import {mapState} from 'vuex'
export default { export default {
name: 'Exp403',
components: {ExceptionPage}, components: {ExceptionPage},
inject: ['layoutMinHeight'], inject: ['layoutMinHeight'],
computed: { computed: {

View File

@ -6,6 +6,7 @@
import ExceptionPage from '@/components/exception/ExceptionPage' import ExceptionPage from '@/components/exception/ExceptionPage'
import {mapState} from 'vuex' import {mapState} from 'vuex'
export default { export default {
name: 'Exp404',
components: {ExceptionPage}, components: {ExceptionPage},
inject: ['layoutMinHeight'], inject: ['layoutMinHeight'],
computed: { computed: {

View File

@ -6,6 +6,7 @@
import ExceptionPage from '@/components/exception/ExceptionPage' import ExceptionPage from '@/components/exception/ExceptionPage'
import {mapState} from 'vuex' import {mapState} from 'vuex'
export default { export default {
name: 'Exp500',
components: {ExceptionPage}, components: {ExceptionPage},
inject: ['layoutMinHeight'], inject: ['layoutMinHeight'],
computed: { computed: {

View File

@ -7,6 +7,7 @@ export default {
animates: ADMIN.animates, animates: ADMIN.animates,
palettes: ADMIN.palettes, palettes: ADMIN.palettes,
routesI18n: {}, routesI18n: {},
dustbins: [],
...config, ...config,
}, },
mutations: { mutations: {
@ -42,6 +43,9 @@ export default {
}, },
setHideSetting(state, hideSetting) { setHideSetting(state, hideSetting) {
state.hideSetting = hideSetting state.hideSetting = hideSetting
},
setDustbins(state, dustbins) {
state.dustbins = dustbins
} }
} }
} }