@ -1,5 +1,9 @@
import type { ComputedRef } from 'vue' ;
import type { Router , RouteRecordNormalized } from 'vue-router' ;
import type {
RouteLocationNormalized ,
Router ,
RouteRecordNormalized ,
} from 'vue-router' ;
import type { TabDefinition } from '@vben-core/typings' ;
@ -53,23 +57,23 @@ export const useTabbarStore = defineStore('core-tabbar', {
/ * *
* Close tabs in bulk
* /
async _bulkCloseByPaths ( paths : string [ ] ) {
this . tabs = this . tabs . filter ( ( item ) = > {
return ! paths . includes ( getTabPath ( item ) ) ;
} ) ;
async _bulkCloseByKeys ( keys : string [ ] ) {
const keySet = new Set ( keys ) ;
this . tabs = this . tabs . filter (
( item ) = > ! keySet . has ( getTabKeyFromTab ( item ) ) ,
) ;
this. updateCacheTabs ( ) ;
await this. updateCacheTabs ( ) ;
} ,
/ * *
* @zh_CN 关 闭 标 签 页
* @param tab
* /
_close ( tab : TabDefinition ) {
const { fullPath } = tab ;
if ( isAffixTab ( tab ) ) {
return ;
}
const index = this . tabs . findIndex ( ( item ) = > item. fullPath === fullPath ) ;
const index = this . tabs . findIndex ( ( item ) = > equalTab( item , tab ) ) ;
index !== - 1 && this . tabs . splice ( index , 1 ) ;
} ,
/ * *
@ -102,14 +106,17 @@ export const useTabbarStore = defineStore('core-tabbar', {
* @zh_CN 添 加 标 签 页
* @param routeTab
* /
addTab ( routeTab : TabDefinition ) {
const tab = cloneTab ( routeTab ) ;
addTab ( routeTab : TabDefinition ) : TabDefinition {
let tab = cloneTab ( routeTab ) ;
if ( ! tab . key ) {
tab . key = getTabKey ( routeTab ) ;
}
if ( ! isTabShown ( tab ) ) {
return ;
return tab ;
}
const tabIndex = this . tabs . findIndex ( ( tab ) = > {
return getTabPath( tab ) === getTabPath ( routeT ab) ;
const tabIndex = this . tabs . findIndex ( ( item ) = > {
return equalTab( item , t ab) ;
} ) ;
if ( tabIndex === - 1 ) {
@ -155,10 +162,11 @@ export const useTabbarStore = defineStore('core-tabbar', {
mergedTab . meta . newTabTitle = curMeta . newTabTitle ;
}
}
tab = mergedTab ;
this . tabs . splice ( tabIndex , 1 , mergedTab ) ;
}
this . updateCacheTabs ( ) ;
return tab ;
} ,
/ * *
* @zh_CN 关 闭 所 有 标 签 页
@ -174,65 +182,63 @@ export const useTabbarStore = defineStore('core-tabbar', {
* @param tab
* /
async closeLeftTabs ( tab : TabDefinition ) {
const index = this . tabs . findIndex (
( item ) = > getTabPath ( item ) === getTabPath ( tab ) ,
) ;
const index = this . tabs . findIndex ( ( item ) = > equalTab ( item , tab ) ) ;
if ( index < 1 ) {
return ;
}
const leftTabs = this . tabs . slice ( 0 , index ) ;
const path s: string [ ] = [ ] ;
const key s: string [ ] = [ ] ;
for ( const item of leftTabs ) {
if ( ! isAffixTab ( item ) ) {
paths. push ( getTabPath ( item ) ) ;
keys. push ( item . key as string ) ;
}
}
await this . _bulkCloseBy Paths( path s) ;
await this . _bulkCloseBy Keys( key s) ;
} ,
/ * *
* @zh_CN 关 闭 其 他 标 签 页
* @param tab
* /
async closeOtherTabs ( tab : TabDefinition ) {
const close Path s = this . tabs . map ( ( item ) = > getTab Path ( item ) ) ;
const close Key s = this . tabs . map ( ( item ) = > getTab KeyFromTab ( item ) ) ;
const path s: string [ ] = [ ] ;
const key s: string [ ] = [ ] ;
for ( const path of closePaths ) {
if ( path !== tab . fullPath ) {
const closeTab = this . tabs . find ( ( item ) = > getTabPath ( item ) === path ) ;
for ( const key of closeKeys ) {
if ( key !== tab . key ) {
const closeTab = this . tabs . find (
( item ) = > getTabKeyFromTab ( item ) === key ,
) ;
if ( ! closeTab ) {
continue ;
}
if ( ! isAffixTab ( closeTab ) ) {
paths. push ( getTabPath ( closeTab ) ) ;
keys. push ( closeTab . key as string ) ;
}
}
}
await this . _bulkCloseBy Paths( path s) ;
await this . _bulkCloseBy Keys( key s) ;
} ,
/ * *
* @zh_CN 关 闭 右 侧 标 签 页
* @param tab
* /
async closeRightTabs ( tab : TabDefinition ) {
const index = this . tabs . findIndex (
( item ) = > getTabPath ( item ) === getTabPath ( tab ) ,
) ;
const index = this . tabs . findIndex ( ( item ) = > equalTab ( item , tab ) ) ;
if ( index !== - 1 && index < this . tabs . length - 1 ) {
const rightTabs = this . tabs . slice ( index + 1 ) ;
const path s: string [ ] = [ ] ;
const key s: string [ ] = [ ] ;
for ( const item of rightTabs ) {
if ( ! isAffixTab ( item ) ) {
paths. push ( getTabPath ( item ) ) ;
keys. push ( item . key as string ) ;
}
}
await this . _bulkCloseBy Paths( path s) ;
await this . _bulkCloseBy Keys( key s) ;
}
} ,
@ -243,15 +249,14 @@ export const useTabbarStore = defineStore('core-tabbar', {
* /
async closeTab ( tab : TabDefinition , router : Router ) {
const { currentRoute } = router ;
// 关闭不是激活选项卡
if ( getTab Path( currentRoute . value ) !== getTabPath ( tab ) ) {
if ( getTab Key( currentRoute . value ) !== getTabKeyFromTab ( tab ) ) {
this . _close ( tab ) ;
this . updateCacheTabs ( ) ;
return ;
}
const index = this . getTabs . findIndex (
( item ) = > getTab Path( item ) === getTabPath ( currentRoute . value ) ,
( item ) = > getTab KeyFromTab( item ) === getTabKey ( currentRoute . value ) ,
) ;
const before = this . getTabs [ index - 1 ] ;
@ -278,7 +283,7 @@ export const useTabbarStore = defineStore('core-tabbar', {
async closeTabByKey ( key : string , router : Router ) {
const originKey = decodeURIComponent ( key ) ;
const index = this . tabs . findIndex (
( item ) = > getTab Path ( item ) === originKey ,
( item ) = > getTab KeyFromTab ( item ) === originKey ,
) ;
if ( index === - 1 ) {
return ;
@ -291,12 +296,12 @@ export const useTabbarStore = defineStore('core-tabbar', {
} ,
/ * *
* 根 据 路 径 获 取 标 签 页
* @param path
* 根 据 tab 的 key 获 取 tab
* @param key
* /
getTabBy Path( path : string ) {
getTabBy Key( key : string ) {
return this . getTabs . find (
( item ) = > getTab Path( item ) === path ,
( item ) = > getTab KeyFromTab( item ) === key ,
) as TabDefinition ;
} ,
/ * *
@ -312,22 +317,19 @@ export const useTabbarStore = defineStore('core-tabbar', {
* @param tab
* /
async pinTab ( tab : TabDefinition ) {
const index = this . tabs . findIndex (
( item ) = > getTabPath ( item ) === getTabPath ( tab ) ,
) ;
if ( index !== - 1 ) {
const oldTab = this . tabs [ index ] ;
tab . meta . affixTab = true ;
tab . meta . title = oldTab ? . meta ? . title as string ;
// this.addTab(tab);
this . tabs . splice ( index , 1 , tab ) ;
const index = this . tabs . findIndex ( ( item ) = > equalTab ( item , tab ) ) ;
if ( index === - 1 ) {
return ;
}
const oldTab = this . tabs [ index ] ;
tab . meta . affixTab = true ;
tab . meta . title = oldTab ? . meta ? . title as string ;
// this.addTab(tab);
this . tabs . splice ( index , 1 , tab ) ;
// 过滤固定tabs, 后面更改affixTabOrder的值的话可能会有问题, 目前行464排序affixTabs没有设置值
const affixTabs = this . tabs . filter ( ( tab ) = > isAffixTab ( tab ) ) ;
// 获得固定tabs的index
const newIndex = affixTabs . findIndex (
( item ) = > getTabPath ( item ) === getTabPath ( tab ) ,
) ;
const newIndex = affixTabs . findIndex ( ( item ) = > equalTab ( item , tab ) ) ;
// 交换位置重新排序
await this . sortTabs ( index , newIndex ) ;
} ,
@ -372,9 +374,7 @@ export const useTabbarStore = defineStore('core-tabbar', {
if ( tab ? . meta ? . newTabTitle ) {
return ;
}
const findTab = this . tabs . find (
( item ) = > getTabPath ( item ) === getTabPath ( tab ) ,
) ;
const findTab = this . tabs . find ( ( item ) = > equalTab ( item , tab ) ) ;
if ( findTab ) {
findTab . meta . newTabTitle = undefined ;
await this . updateCacheTabs ( ) ;
@ -419,9 +419,7 @@ export const useTabbarStore = defineStore('core-tabbar', {
* setTabTitle ( tab , computed ( ( ) = > t ( 'common.dashboard' ) ) ) ;
* /
async setTabTitle ( tab : TabDefinition , title : ComputedRef < string > | string ) {
const findTab = this . tabs . find (
( item ) = > getTabPath ( item ) === getTabPath ( tab ) ,
) ;
const findTab = this . tabs . find ( ( item ) = > equalTab ( item , tab ) ) ;
if ( findTab ) {
findTab . meta . newTabTitle = title ;
@ -462,17 +460,15 @@ export const useTabbarStore = defineStore('core-tabbar', {
* @param tab
* /
async unpinTab ( tab : TabDefinition ) {
const index = this . tabs . findIndex (
( item ) = > getTabPath ( item ) === getTabPath ( tab ) ,
) ;
if ( index !== - 1 ) {
const oldTab = this . tabs [ index ] ;
tab . meta . affixTab = false ;
tab . meta . title = oldTab ? . meta ? . title as string ;
// this.addTab(tab);
this . tabs . splice ( index , 1 , tab ) ;
const index = this . tabs . findIndex ( ( item ) = > equalTab ( item , tab ) ) ;
if ( index === - 1 ) {
return ;
}
const oldTab = this . tabs [ index ] ;
tab . meta . affixTab = false ;
tab . meta . title = oldTab ? . meta ? . title as string ;
// this.addTab(tab);
this . tabs . splice ( index , 1 , tab ) ;
// 过滤固定tabs, 后面更改affixTabOrder的值的话可能会有问题, 目前行464排序affixTabs没有设置值
const affixTabs = this . tabs . filter ( ( tab ) = > isAffixTab ( tab ) ) ;
// 获得固定tabs的index,使用固定tabs的下一个位置也就是活动tabs的第一个位置
@ -605,11 +601,49 @@ function isTabShown(tab: TabDefinition) {
}
/ * *
* @zh_CN 获 取 标 签 页 路 径
* 从 route 获 取 tab 页 的 key
* @param tab
* /
function getTabPath ( tab : RouteRecordNormalized | TabDefinition ) {
return decodeURIComponent ( ( tab as TabDefinition ) . fullPath || tab . path ) ;
function getTabKey ( tab : RouteLocationNormalized | RouteRecordNormalized ) {
const {
fullPath ,
path ,
meta : { fullPathKey } = { } ,
query = { } ,
} = tab as RouteLocationNormalized ;
// pageKey可能是数组( 查询参数重复时可能出现)
const pageKey = Array . isArray ( query . pageKey )
? query . pageKey [ 0 ]
: query . pageKey ;
let rawKey ;
if ( pageKey ) {
rawKey = pageKey ;
} else {
rawKey = fullPathKey === false ? path : ( fullPath ? ? path ) ;
}
try {
return decodeURIComponent ( rawKey ) ;
} catch {
return rawKey ;
}
}
/ * *
* 从 tab 获 取 tab 页 的 key
* 如 果 tab 没 有 key , 那 么 就 从 route 获 取 key
* @param tab
* /
function getTabKeyFromTab ( tab : TabDefinition ) : string {
return tab . key ? ? getTabKey ( tab ) ;
}
/ * *
* 比 较 两 个 tab 是 否 相 等
* @param a
* @param b
* /
function equalTab ( a : TabDefinition , b : TabDefinition ) {
return getTabKeyFromTab ( a ) === getTabKeyFromTab ( b ) ;
}
function routeToTab ( route : RouteRecordNormalized ) {
@ -617,5 +651,8 @@ function routeToTab(route: RouteRecordNormalized) {
meta : route.meta ,
name : route.name ,
path : route.path ,
key : getTabKey ( route ) ,
} as TabDefinition ;
}
export { getTabKey } ;