- 首页 tab 固定不可关闭,tab 持久化(刷新保留) - 关闭激活 tab 跳转到相邻 tab(而非最后一个) - 自定义 tab 条 + 右键菜单:关闭其他/左侧/右侧/全部 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
58 lines
1.7 KiB
TypeScript
58 lines
1.7 KiB
TypeScript
import { ref } from 'vue'
|
||
import { defineStore } from 'pinia'
|
||
|
||
export interface TabItem {
|
||
path: string
|
||
title: string
|
||
closable: boolean
|
||
}
|
||
|
||
export const HOME_PATH = '/'
|
||
|
||
/** 多页签状态(持久化,刷新保留)。 */
|
||
export const useTabsStore = defineStore(
|
||
'tabsStore',
|
||
() => {
|
||
const tabs = ref<TabItem[]>([{ path: HOME_PATH, title: '首页', closable: false }])
|
||
|
||
function addTab(tab: TabItem): void {
|
||
if (!tabs.value.some((t) => t.path === tab.path)) {
|
||
tabs.value.push(tab)
|
||
}
|
||
}
|
||
|
||
function removeTab(path: string): void {
|
||
const tab = tabs.value.find((t) => t.path === path)
|
||
if (!tab || !tab.closable) return
|
||
tabs.value = tabs.value.filter((t) => t.path !== path)
|
||
}
|
||
|
||
/** 关闭其他(保留首页与指定 tab)。 */
|
||
function removeOthers(path: string): void {
|
||
tabs.value = tabs.value.filter((t) => !t.closable || t.path === path)
|
||
}
|
||
|
||
/** 关闭左侧(保留首页、指定 tab 及其右侧)。 */
|
||
function removeLeft(path: string): void {
|
||
const index = tabs.value.findIndex((t) => t.path === path)
|
||
if (index < 0) return
|
||
tabs.value = tabs.value.filter((t, i) => !t.closable || i >= index)
|
||
}
|
||
|
||
/** 关闭右侧(保留首页、指定 tab 及其左侧)。 */
|
||
function removeRight(path: string): void {
|
||
const index = tabs.value.findIndex((t) => t.path === path)
|
||
if (index < 0) return
|
||
tabs.value = tabs.value.filter((t, i) => !t.closable || i <= index)
|
||
}
|
||
|
||
/** 关闭全部(仅保留首页)。 */
|
||
function removeAll(): void {
|
||
tabs.value = tabs.value.filter((t) => !t.closable)
|
||
}
|
||
|
||
return { tabs, addTab, removeTab, removeOthers, removeLeft, removeRight, removeAll }
|
||
},
|
||
{ persist: true },
|
||
)
|