import { defineStore } from 'pinia' import * as _ from 'lodash-es' import { Location, RouteRecord } from 'vue-router' import { GlobalActions } from '@/util/enum' import Vue from 'vue' type Dictionary = { [key: string]: T } interface Source { name: string path: string title: string query: Dictionary params: Dictionary closable: boolean activeName: string componentName: string } export interface IReusetabState { source: Source[] to?: Location matched: RouteRecord[] } export const useReuseTabStore = defineStore('useReuseTabStore', { state: (): IReusetabState => { return { source: [], to: {}, matched: [], } }, actions: { changeSource(param) { this.source = param.source Vue.prototype.$setGlobalState({ action: GlobalActions.SetReuseTab, reuseTabSource: this.source, }) }, changeTo(param) { this.to = param }, add(param) { const oldTables = this.source const targetName = param.name const activeName = param.activeName const isPassport = _.startsWith(targetName, '/passport') if (isPassport === true) { return } if (activeName === targetName) { return } const index = oldTables.findIndex((v) => v.name === param.name) // 重载一次路由,防止路由参数丢失 if (index >= 0) { oldTables[index] = param } else { oldTables.push(param) } if (oldTables.length > 6) { oldTables.shift() } this.changeSource({ source: oldTables }) }, remove(param) { const source = this.source const { activeName, name, next } = param const targetName = name // 关闭当前页 if (activeName === targetName) { // 下一步路由 if (typeof next !== 'undefined') { this.changeTo(next) } else { let index: number = source.findIndex((tab) => tab.name === targetName) index = index > 0 ? index - 1 : index + 1 this.changeTo(source[index]) } } const newTabs = _.filter(source, (tab) => tab.name !== targetName) this.changeSource({ source: newTabs }) }, changeTitle(param) { const { title, route } = param const list = this.source list.forEach((item) => { if (item.name === route.name) { item.title = title } }) this.changeSource({ source: list }) }, clear() { this.source = [] this.to = {} }, setMatched(payload) { this.matched = payload }, }, })