113 lines
3.4 KiB
TypeScript
113 lines
3.4 KiB
TypeScript
// src/stores/tab.ts
|
||
import { defineStore } from 'pinia'
|
||
import { ref } from 'vue'
|
||
|
||
export const useTabStore = defineStore('tabs', () => {
|
||
interface TabItem<T = Record<string, any>> {
|
||
id: string; // 标签唯一标识
|
||
title: string; // 标签标题
|
||
componentName: string; // 组件名称
|
||
props?: T; // 传递给组件的 props(可选,泛型适配不同组件)
|
||
}
|
||
const defaultTabs :TabItem[]= [
|
||
{ id: 'XmView', title: '项目卡片', componentName: 'XmView' }
|
||
]
|
||
|
||
const tabs = ref([
|
||
...defaultTabs
|
||
])
|
||
const activeTabId = ref('XmView')
|
||
|
||
const ensureActiveValid = () => {
|
||
const activeExists = tabs.value.some(t => t.id === activeTabId.value)
|
||
if (!activeExists) {
|
||
activeTabId.value = tabs.value[0]?.id || 'XmView'
|
||
}
|
||
}
|
||
|
||
const openTab = (config: { id: string; title: string; componentName: string; props?: any }) => {
|
||
const exists = tabs.value.some(t => t.id === config.id)
|
||
if (!exists) {
|
||
tabs.value = [...tabs.value, config]
|
||
}
|
||
activeTabId.value = config.id
|
||
}
|
||
|
||
const removeTab = (id: string) => {
|
||
if (id === 'XmView') return // 首页不可删除
|
||
const index = tabs.value.findIndex(t => t.id === id)
|
||
if (index < 0) return
|
||
const wasActive = activeTabId.value === id
|
||
tabs.value = tabs.value.filter(t => t.id !== id)
|
||
|
||
if (tabs.value.length === 0) {
|
||
tabs.value = [...defaultTabs]
|
||
}
|
||
|
||
if (wasActive) {
|
||
const fallbackIndex = Math.max(0, Math.min(index - 1, tabs.value.length - 1))
|
||
activeTabId.value = tabs.value[fallbackIndex]?.id || 'XmView'
|
||
return
|
||
}
|
||
|
||
const activeStillExists = tabs.value.some(t => t.id === activeTabId.value)
|
||
if (!activeStillExists) {
|
||
activeTabId.value = tabs.value[0]?.id || 'XmView'
|
||
}
|
||
}
|
||
|
||
const closeAllTabs = () => {
|
||
tabs.value = tabs.value.filter(t => t.id === 'XmView')
|
||
if (tabs.value.length === 0) tabs.value = [...defaultTabs]
|
||
activeTabId.value = 'XmView'
|
||
}
|
||
|
||
const closeLeftTabs = (targetId: string) => {
|
||
const targetIndex = tabs.value.findIndex(t => t.id === targetId)
|
||
if (targetIndex < 0) return
|
||
tabs.value = tabs.value.filter((tab, index) => tab.id === 'XmView' || index >= targetIndex)
|
||
ensureActiveValid()
|
||
}
|
||
|
||
const closeRightTabs = (targetId: string) => {
|
||
const targetIndex = tabs.value.findIndex(t => t.id === targetId)
|
||
if (targetIndex < 0) return
|
||
tabs.value = tabs.value.filter((tab, index) => tab.id === 'XmView' || index <= targetIndex)
|
||
ensureActiveValid()
|
||
}
|
||
|
||
const closeOtherTabs = (targetId: string) => {
|
||
tabs.value = tabs.value.filter(tab => tab.id === 'XmView' || tab.id === targetId)
|
||
if (tabs.value.length === 0) tabs.value = [...defaultTabs]
|
||
if (targetId === 'XmView') {
|
||
activeTabId.value = 'XmView'
|
||
return
|
||
}
|
||
activeTabId.value = tabs.value.some(t => t.id === targetId) ? targetId : 'XmView'
|
||
}
|
||
|
||
const resetTabs = () => {
|
||
tabs.value = [...defaultTabs]
|
||
activeTabId.value = 'XmView'
|
||
}
|
||
|
||
return {
|
||
tabs,
|
||
activeTabId,
|
||
openTab,
|
||
removeTab,
|
||
closeAllTabs,
|
||
closeLeftTabs,
|
||
closeRightTabs,
|
||
closeOtherTabs,
|
||
resetTabs
|
||
}
|
||
}, {
|
||
// --- 关键配置:开启持久化 ---
|
||
persist: {
|
||
key: 'tabs', // 存储在 localStorage 里的 key
|
||
storage: localStorage, // 也可以改用 sessionStorage
|
||
pick: ['tabs', 'activeTabId'], // 指定哪些变量需要持久化
|
||
}
|
||
})
|