添加持久化标签页开关功能

This commit is contained in:
RuoYi
2026-03-22 21:03:58 +08:00
parent 0f734eda88
commit ec0ca11cc6
5 changed files with 79 additions and 3 deletions

View File

@@ -65,6 +65,11 @@
<el-switch v-model="tagsView" class="drawer-switch" /> <el-switch v-model="tagsView" class="drawer-switch" />
</div> </div>
<div class="drawer-item">
<span>持久化标签页</span>
<el-switch v-model="tagsViewPersist" :disabled="!tagsView" class="drawer-switch" />
</div>
<div class="drawer-item"> <div class="drawer-item">
<span>显示页签图标</span> <span>显示页签图标</span>
<el-switch v-model="tagsIcon" :disabled="!tagsView" class="drawer-switch" /> <el-switch v-model="tagsIcon" :disabled="!tagsView" class="drawer-switch" />
@@ -125,6 +130,20 @@ export default {
}) })
} }
}, },
tagsViewPersist: {
get() {
return this.$store.state.settings.tagsViewPersist
},
set(val) {
this.$store.dispatch('settings/changeSetting', {
key: 'tagsViewPersist',
value: val
})
if (!val) {
this.$cache.local.remove('tags-view-visited')
}
}
},
tagsView: { tagsView: {
get() { get() {
return this.$store.state.settings.tagsView return this.$store.state.settings.tagsView
@@ -237,6 +256,7 @@ export default {
"navType":${this.navType}, "navType":${this.navType},
"tagsView":${this.tagsView}, "tagsView":${this.tagsView},
"tagsIcon":${this.tagsIcon}, "tagsIcon":${this.tagsIcon},
"tagsViewPersist":${this.tagsViewPersist},
"fixedHeader":${this.fixedHeader}, "fixedHeader":${this.fixedHeader},
"sidebarLogo":${this.sidebarLogo}, "sidebarLogo":${this.sidebarLogo},
"dynamicTitle":${this.dynamicTitle}, "dynamicTitle":${this.dynamicTitle},

View File

@@ -177,10 +177,13 @@ export default {
return tags return tags
}, },
initTags() { initTags() {
if (this.$store.state.settings.tagsViewPersist) {
this.$store.dispatch('tagsView/loadPersistedViews')
}
const affixTags = this.affixTags = this.filterAffixTags(this.routes) const affixTags = this.affixTags = this.filterAffixTags(this.routes)
for (const tag of affixTags) { for (const tag of affixTags) {
if (tag.name) { if (tag.name) {
this.$store.dispatch('tagsView/addVisitedView', tag) this.$store.dispatch('tagsView/addAffixView', tag)
} }
} }
}, },

View File

@@ -23,7 +23,12 @@ module.exports = {
* 是否显示 tagsView * 是否显示 tagsView
*/ */
tagsView: true, tagsView: true,
/**
* 持久化标签页
*/
tagsViewPersist: false,
/** /**
* 显示页签图标 * 显示页签图标
*/ */

View File

@@ -1,7 +1,7 @@
import defaultSettings from '@/settings' import defaultSettings from '@/settings'
import { useDynamicTitle } from '@/utils/dynamicTitle' import { useDynamicTitle } from '@/utils/dynamicTitle'
const { sideTheme, showSettings, navType, tagsView, tagsIcon, fixedHeader, sidebarLogo, dynamicTitle, footerVisible, footerContent } = defaultSettings const { sideTheme, showSettings, navType, tagsView, tagsViewPersist, tagsIcon, fixedHeader, sidebarLogo, dynamicTitle, footerVisible, footerContent } = defaultSettings
const storageSetting = JSON.parse(localStorage.getItem('layout-setting')) || '' const storageSetting = JSON.parse(localStorage.getItem('layout-setting')) || ''
const state = { const state = {
@@ -11,6 +11,7 @@ const state = {
showSettings: showSettings, showSettings: showSettings,
navType: storageSetting.navType === undefined ? navType : storageSetting.navType, navType: storageSetting.navType === undefined ? navType : storageSetting.navType,
tagsView: storageSetting.tagsView === undefined ? tagsView : storageSetting.tagsView, tagsView: storageSetting.tagsView === undefined ? tagsView : storageSetting.tagsView,
tagsViewPersist: storageSetting.tagsViewPersist === undefined ? tagsViewPersist : storageSetting.tagsViewPersist,
tagsIcon: storageSetting.tagsIcon === undefined ? tagsIcon : storageSetting.tagsIcon, tagsIcon: storageSetting.tagsIcon === undefined ? tagsIcon : storageSetting.tagsIcon,
fixedHeader: storageSetting.fixedHeader === undefined ? fixedHeader : storageSetting.fixedHeader, fixedHeader: storageSetting.fixedHeader === undefined ? fixedHeader : storageSetting.fixedHeader,
sidebarLogo: storageSetting.sidebarLogo === undefined ? sidebarLogo : storageSetting.sidebarLogo, sidebarLogo: storageSetting.sidebarLogo === undefined ? sidebarLogo : storageSetting.sidebarLogo,

View File

@@ -1,3 +1,26 @@
import store from '@/store'
import cache from '@/plugins/cache'
const PERSIST_KEY = 'tags-view-visited'
function isPersistEnabled() {
return store.state.settings.tagsViewPersist
}
function saveVisitedViews(views) {
if (!isPersistEnabled()) return
const toSave = views.filter(v => !(v.meta && v.meta.affix)).map(v => ({ path: v.path, fullPath: v.fullPath, name: v.name, title: v.title, query: v.query, meta: v.meta }))
cache.local.setJSON(PERSIST_KEY, toSave)
}
function loadVisitedViews() {
return cache.local.getJSON(PERSIST_KEY) || []
}
function clearVisitedViews() {
cache.local.remove(PERSIST_KEY)
}
const state = { const state = {
visitedViews: [], visitedViews: [],
cachedViews: [], cachedViews: [],
@@ -20,6 +43,15 @@ const mutations = {
title: view.meta.title || 'no-name' title: view.meta.title || 'no-name'
}) })
) )
saveVisitedViews(state.visitedViews)
},
ADD_VISITED_VIEW_FIRST: (state, view) => {
if (state.visitedViews.some(v => v.path === view.path)) return
state.visitedViews.unshift(
Object.assign({}, view, {
title: view.meta.title || 'no-name'
})
)
}, },
ADD_CACHED_VIEW: (state, view) => { ADD_CACHED_VIEW: (state, view) => {
if (state.cachedViews.includes(view.name)) return if (state.cachedViews.includes(view.name)) return
@@ -35,6 +67,7 @@ const mutations = {
} }
} }
state.iframeViews = state.iframeViews.filter(item => item.path !== view.path) state.iframeViews = state.iframeViews.filter(item => item.path !== view.path)
saveVisitedViews(state.visitedViews)
}, },
DEL_IFRAME_VIEW: (state, view) => { DEL_IFRAME_VIEW: (state, view) => {
state.iframeViews = state.iframeViews.filter(item => item.path !== view.path) state.iframeViews = state.iframeViews.filter(item => item.path !== view.path)
@@ -49,6 +82,7 @@ const mutations = {
return v.meta.affix || v.path === view.path return v.meta.affix || v.path === view.path
}) })
state.iframeViews = state.iframeViews.filter(item => item.path === view.path) state.iframeViews = state.iframeViews.filter(item => item.path === view.path)
saveVisitedViews(state.visitedViews)
}, },
DEL_OTHERS_CACHED_VIEWS: (state, view) => { DEL_OTHERS_CACHED_VIEWS: (state, view) => {
const index = state.cachedViews.indexOf(view.name) const index = state.cachedViews.indexOf(view.name)
@@ -63,6 +97,7 @@ const mutations = {
const affixTags = state.visitedViews.filter(tag => tag.meta.affix) const affixTags = state.visitedViews.filter(tag => tag.meta.affix)
state.visitedViews = affixTags state.visitedViews = affixTags
state.iframeViews = [] state.iframeViews = []
clearVisitedViews()
}, },
DEL_ALL_CACHED_VIEWS: state => { DEL_ALL_CACHED_VIEWS: state => {
state.cachedViews = [] state.cachedViews = []
@@ -94,6 +129,7 @@ const mutations = {
} }
return false return false
}) })
saveVisitedViews(state.visitedViews)
}, },
DEL_LEFT_VIEWS: (state, view) => { DEL_LEFT_VIEWS: (state, view) => {
const index = state.visitedViews.findIndex(v => v.path === view.path) const index = state.visitedViews.findIndex(v => v.path === view.path)
@@ -114,6 +150,7 @@ const mutations = {
} }
return false return false
}) })
saveVisitedViews(state.visitedViews)
} }
} }
@@ -128,6 +165,9 @@ const actions = {
addVisitedView({ commit }, view) { addVisitedView({ commit }, view) {
commit('ADD_VISITED_VIEW', view) commit('ADD_VISITED_VIEW', view)
}, },
addAffixView({ commit }, view) {
commit('ADD_VISITED_VIEW_FIRST', view)
},
addCachedView({ commit }, view) { addCachedView({ commit }, view) {
commit('ADD_CACHED_VIEW', view) commit('ADD_CACHED_VIEW', view)
}, },
@@ -218,6 +258,13 @@ const actions = {
resolve([...state.visitedViews]) resolve([...state.visitedViews])
}) })
}, },
// 恢复持久化的 tags
loadPersistedViews({ commit }) {
const views = loadVisitedViews()
views.forEach(view => {
commit('ADD_VISITED_VIEW', view)
})
},
} }
export default { export default {