123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189 |
- import { useStorage } from '@vueuse/core'
- import { acceptHMRUpdate, defineStore } from 'pinia'
- import type { RouteRecordNameGeneric } from 'vue-router'
- export type Key = string | number | undefined
- export interface Tab {
- id?: Key
- path: string
- icon?: string
- title?: string
- name?: RouteRecordNameGeneric
- componentName?: string
- locked?: boolean
- pinned?: boolean
- keepAlive?: boolean
- }
- export const useTabsStore = defineStore('tabsStore', () => {
- const tabs = useStorage<Tab[]>('tabs', [])
- const tabActivePath = useStorage<string>('tabActivePath', '')
- function findTabIndex(id: Key) {
- return tabs.value.findIndex((tab) => tab.id === id)
- }
- function sortTabs() {
- tabs.value.sort((a, b) => {
- if (a.pinned && !b.pinned) return -1
- if (!a.pinned && b.pinned) return 1
- return 0
- })
- }
- function createTab(tab: Tab) {
- if (!tabs.value.some(({ path }) => path === tab.path)) {
- const id = Date.now()
- tabs.value.push({ ...tab, id })
- if (tab.pinned) {
- sortTabs()
- }
- }
- setTabActivePath(tab.path)
- }
- function getTab(tabId: Key) {
- return tabs.value.find(({ id }) => id === tabId)
- }
- function updateTab(id: Key, updateProperties: Partial<Tab>) {
- const index = findTabIndex(id)
- if (index !== -1) {
- const targetTab = tabs.value[index]
- tabs.value[index] = { ...targetTab, ...updateProperties }
- if ('pinned' in updateProperties && updateProperties.pinned !== targetTab.pinned) {
- sortTabs()
- }
- }
- }
- function setTabs(value: Tab[]) {
- tabs.value = value
- }
- function removeTab(tabIds: Key | Key[]) {
- const removeIdsSet = new Set(Array.isArray(tabIds) ? tabIds : [tabIds])
- const nextTabs: Tab[] = []
- let activeIndex = -1
- for (let i = 0; i < tabs.value.length; i++) {
- const tab = tabs.value[i]
- if (tab.path === tabActivePath.value) activeIndex = i
- if (!removeIdsSet.has(tab.id)) nextTabs.push(tab)
- }
- if (activeIndex !== -1 && removeIdsSet.has(tabs.value[activeIndex].id)) {
- let nextActivePath = ''
- for (let i = activeIndex + 1; i < tabs.value.length; i++) {
- if (!removeIdsSet.has(tabs.value[i].id)) {
- nextActivePath = tabs.value[i].path
- break
- }
- }
- if (!nextActivePath) {
- for (let i = activeIndex - 1; i >= 0; i--) {
- if (!removeIdsSet.has(tabs.value[i].id)) {
- nextActivePath = tabs.value[i].path
- break
- }
- }
- }
- if (nextActivePath) {
- setTabActivePath(nextActivePath)
- } else {
- setTabActivePath('/')
- }
- }
- tabs.value = nextTabs
- }
- function clearTabs() {
- tabs.value = []
- }
- function getRemovableIdsBefore(id: Key) {
- const removableIds: Key[] = []
- for (const tab of tabs.value) {
- if (tab.id === id) break
- if (!tab.locked && !tab.pinned) {
- removableIds.push(tab.id)
- }
- }
- return removableIds
- }
- function getRemovableIdsAfter(id: Key) {
- const removableIds: Key[] = []
- for (let i = tabs.value.length - 1; i >= 0; i--) {
- if (tabs.value[i].id === id) break
- if (!tabs.value[i].locked && !tabs.value[i].pinned) {
- removableIds.push(tabs.value[i].id)
- }
- }
- return removableIds
- }
- function getRemovableIdsOther(id: Key) {
- const removableIds: Key[] = []
- for (const tab of tabs.value) {
- if (tab.id !== id && !tab.locked && !tab.pinned) {
- removableIds.push(tab.id)
- }
- }
- return removableIds
- }
- function getRemovableIds() {
- const removableIds: Key[] = []
- for (const tab of tabs.value) {
- if (!tab.locked && !tab.pinned) {
- removableIds.push(tab.id)
- }
- }
- return removableIds
- }
- function setTabActivePath(key: string) {
- tabActivePath.value = key
- }
- return {
- tabs,
- tabActivePath,
- setTabActivePath,
- getTab,
- createTab,
- updateTab,
- removeTab,
- setTabs,
- clearTabs,
- getRemovableIdsBefore,
- getRemovableIdsAfter,
- getRemovableIdsOther,
- getRemovableIds,
- }
- })
- if (import.meta.hot) {
- import.meta.hot.accept(acceptHMRUpdate(useTabsStore, import.meta.hot))
- }
|