2022-08-12 10:44:09 +00:00
|
|
|
import { defineStore } from 'pinia'
|
|
|
|
|
import { isExternal } from '@/utils/validate'
|
|
|
|
|
import type {
|
|
|
|
|
LocationQuery,
|
|
|
|
|
RouteLocationNormalized,
|
|
|
|
|
RouteParamsRaw,
|
|
|
|
|
Router,
|
|
|
|
|
RouteRecordName
|
|
|
|
|
} from 'vue-router'
|
|
|
|
|
import { PageEnum } from '@/enums/pageEnum'
|
|
|
|
|
|
|
|
|
|
interface TabItem {
|
|
|
|
|
name: RouteRecordName
|
|
|
|
|
path: string
|
|
|
|
|
title?: string
|
|
|
|
|
query?: LocationQuery
|
|
|
|
|
params?: RouteParamsRaw
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
interface TabsSate {
|
|
|
|
|
cacheTabList: Set<string>
|
|
|
|
|
tabList: TabItem[]
|
|
|
|
|
tasMap: Record<string, TabItem>
|
|
|
|
|
indexRouteName: RouteRecordName
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const getHasTabIndex = (path: string, tabList: TabItem[]) => {
|
|
|
|
|
return tabList.findIndex((item) => item.path == path)
|
|
|
|
|
}
|
|
|
|
|
|
2022-08-29 11:06:22 +00:00
|
|
|
const isCannotAddRoute = (route: RouteLocationNormalized, router: Router) => {
|
|
|
|
|
const { path, meta, name } = route
|
2022-08-12 10:44:09 +00:00
|
|
|
if (!path || isExternal(path)) return true
|
|
|
|
|
if (meta?.hideTab) return true
|
2022-08-29 11:06:22 +00:00
|
|
|
if (!router.hasRoute(name!)) return true
|
2022-08-12 10:44:09 +00:00
|
|
|
if (([PageEnum.LOGIN, PageEnum.ERROR_403] as string[]).includes(path)) {
|
|
|
|
|
return true
|
|
|
|
|
}
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const findTabsIndex = (path: string, tabList: TabItem[]) => {
|
|
|
|
|
return tabList.findIndex((item) => item.path === path)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export const getRouteParams = (tabItem: TabItem) => {
|
|
|
|
|
const { params, path, query } = tabItem
|
|
|
|
|
return {
|
|
|
|
|
params: params || {},
|
|
|
|
|
path,
|
|
|
|
|
query: query || {}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const useTabsStore = defineStore({
|
|
|
|
|
id: 'tabs',
|
|
|
|
|
state: (): TabsSate => ({
|
|
|
|
|
cacheTabList: new Set(),
|
|
|
|
|
tabList: [],
|
|
|
|
|
tasMap: {},
|
|
|
|
|
indexRouteName: ''
|
|
|
|
|
}),
|
|
|
|
|
getters: {
|
|
|
|
|
getTabList(): TabItem[] {
|
|
|
|
|
return this.tabList
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
actions: {
|
|
|
|
|
setRouteName(name: RouteRecordName) {
|
|
|
|
|
this.indexRouteName = name
|
|
|
|
|
},
|
|
|
|
|
resetState() {
|
|
|
|
|
this.cacheTabList = new Set()
|
|
|
|
|
this.tabList = []
|
|
|
|
|
this.tasMap = {}
|
|
|
|
|
this.indexRouteName = ''
|
|
|
|
|
},
|
2022-08-29 11:06:22 +00:00
|
|
|
addTab(route: RouteLocationNormalized, router: Router) {
|
2022-08-12 10:44:09 +00:00
|
|
|
const { name, path, query, meta, params } = route
|
2022-08-29 11:06:22 +00:00
|
|
|
if (isCannotAddRoute(route, router)) return
|
2022-08-12 10:44:09 +00:00
|
|
|
const hasTabIndex = getHasTabIndex(path!, this.tabList)
|
|
|
|
|
|
|
|
|
|
const tabItem = {
|
|
|
|
|
name: name!,
|
|
|
|
|
path,
|
|
|
|
|
title: meta?.title,
|
|
|
|
|
query,
|
|
|
|
|
params
|
|
|
|
|
}
|
|
|
|
|
this.tasMap[path] = tabItem
|
|
|
|
|
if (hasTabIndex != -1) {
|
|
|
|
|
this.tabList.splice(hasTabIndex, 1, tabItem)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
this.tabList.push(tabItem)
|
|
|
|
|
},
|
|
|
|
|
removeTab(path: string, router: Router) {
|
|
|
|
|
const { currentRoute, push } = router
|
|
|
|
|
const index = findTabsIndex(path, this.tabList)
|
|
|
|
|
// 移除tab
|
|
|
|
|
if (this.tabList.length > 1) {
|
|
|
|
|
index !== -1 && this.tabList.splice(index, 1)
|
|
|
|
|
}
|
|
|
|
|
if (path !== currentRoute.value.path) {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
// 删除选中的tab
|
|
|
|
|
let toTab: TabItem | null = null
|
|
|
|
|
|
|
|
|
|
if (index === 0) {
|
|
|
|
|
toTab = this.tabList[index]
|
|
|
|
|
} else {
|
|
|
|
|
toTab = this.tabList[index - 1]
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const toRoute = getRouteParams(toTab)
|
|
|
|
|
push(toRoute)
|
|
|
|
|
},
|
|
|
|
|
removeOtherTab(path: string) {
|
|
|
|
|
this.tabList = this.tabList.filter((item) => item.path == path)
|
|
|
|
|
},
|
|
|
|
|
removeAllTab(router: Router) {
|
|
|
|
|
const { push, currentRoute } = router
|
|
|
|
|
const { path, name } = unref(currentRoute)
|
|
|
|
|
if (name == this.indexRouteName) {
|
|
|
|
|
this.removeOtherTab(path)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
this.tabList = []
|
|
|
|
|
push(PageEnum.INDEX)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
export default useTabsStore
|