1+ import type { RouteItem } from '@/types/route' ;
12import { create } from 'zustand' ;
23import { persist , type PersistOptions } from 'zustand/middleware' ;
3- import type { RouteItem } from '@/types/route' ;
44
55export interface TabItem {
66 key : string ;
@@ -10,6 +10,7 @@ export interface TabItem {
1010 closable : boolean ;
1111 component ?: React . ComponentType ;
1212 route ?: RouteItem ;
13+ reloadKey ?: number ; // 用于强制重新加载的时间戳
1314}
1415
1516interface TabStore {
@@ -18,7 +19,7 @@ interface TabStore {
1819 // 当前激活的tab key
1920 activeKey : string ;
2021 // 添加tab
21- addTab : ( tab : TabItem , options ?: { insertAt ?: 'head' | 'tail' , activate ?: boolean } ) => void ;
22+ addTab : ( tab : TabItem , options ?: { insertAt ?: 'head' | 'tail' ; activate ?: boolean } ) => void ;
2223 // 移除tab
2324 removeTab : ( targetKey : string ) => string ;
2425 // 设置激活的tab
@@ -53,14 +54,14 @@ export const useTabStore = create<TabStore>()(
5354 tabs : [ ] ,
5455 activeKey : '' ,
5556
56- addTab : ( tab : TabItem , options ?: { insertAt ?: 'head' | 'tail' , activate ?: boolean } ) => {
57+ addTab : ( tab : TabItem , options ?: { insertAt ?: 'head' | 'tail' ; activate ?: boolean } ) => {
5758 const { tabs, activeKey } = get ( ) ;
5859 const existingTabIndex = tabs . findIndex ( ( t ) => t . key === tab . key ) ;
5960
6061 if ( existingTabIndex === - 1 ) {
6162 // 新tab,根据选项决定插入位置
6263 const { insertAt = 'tail' , activate = true } = options || { } ;
63-
64+
6465 let newTabs : TabItem [ ] ;
6566 if ( insertAt === 'head' ) {
6667 // 头插入:添加到数组开头
@@ -101,10 +102,10 @@ export const useTabStore = create<TabStore>()(
101102 newActiveKey = '' ;
102103 } else if ( targetIndex === 0 ) {
103104 // 关闭的是第一个,激活第一个
104- newActiveKey = newTabs [ 0 ] . key ;
105+ newActiveKey = newTabs . length > 0 ? ( newTabs [ 0 ] ? .key ?? '' ) : '' ;
105106 } else {
106107 // 激活前一个
107- newActiveKey = newTabs [ targetIndex - 1 ] . key ;
108+ newActiveKey = newTabs [ targetIndex - 1 ] ? .key ?? '' ;
108109 }
109110 }
110111
@@ -134,9 +135,9 @@ export const useTabStore = create<TabStore>()(
134135 if ( homeTab && homeTab . key !== targetKey ) {
135136 newTabs . push ( homeTab ) ;
136137 }
137-
138+
138139 // 如果当前激活的tab不在保留的tab中,需要激活目标tab
139- const newActiveKey = newTabs . some ( tab => tab . key === activeKey ) ? activeKey : targetKey ;
140+ const newActiveKey = newTabs . some ( ( tab ) => tab . key === activeKey ) ? activeKey : targetKey ;
140141 set ( {
141142 tabs : newTabs ,
142143 activeKey : newActiveKey ,
@@ -151,20 +152,20 @@ export const useTabStore = create<TabStore>()(
151152 const targetIndex = tabs . findIndex ( ( tab ) => tab . key === targetKey ) ;
152153 if ( targetIndex > 0 ) {
153154 let newTabs = tabs . slice ( targetIndex ) ;
154-
155+
155156 // 如果homePath的tab在左侧被删除了,需要保留它
156157 if ( homePath ) {
157158 const homeTab = tabs . find ( ( tab ) => tab . key === homePath ) ;
158- if ( homeTab && ! newTabs . some ( tab => tab . key === homePath ) ) {
159+ if ( homeTab && ! newTabs . some ( ( tab ) => tab . key === homePath ) ) {
159160 newTabs = [ homeTab , ...newTabs ] ;
160161 }
161162 }
162-
163+
163164 // 如果当前激活的tab不在保留的tab中,需要激活目标tab
164- const newActiveKey = newTabs . some ( tab => tab . key === activeKey ) ? activeKey : targetKey ;
165- set ( {
165+ const newActiveKey = newTabs . some ( ( tab ) => tab . key === activeKey ) ? activeKey : targetKey ;
166+ set ( {
166167 tabs : newTabs ,
167- activeKey : newActiveKey
168+ activeKey : newActiveKey ,
168169 } ) ;
169170 return newActiveKey ;
170171 }
@@ -176,20 +177,20 @@ export const useTabStore = create<TabStore>()(
176177 const targetIndex = tabs . findIndex ( ( tab ) => tab . key === targetKey ) ;
177178 if ( targetIndex >= 0 && targetIndex < tabs . length - 1 ) {
178179 let newTabs = tabs . slice ( 0 , targetIndex + 1 ) ;
179-
180+
180181 // 如果homePath的tab在右侧被删除了,需要保留它
181182 if ( homePath ) {
182183 const homeTab = tabs . find ( ( tab ) => tab . key === homePath ) ;
183- if ( homeTab && ! newTabs . some ( tab => tab . key === homePath ) ) {
184+ if ( homeTab && ! newTabs . some ( ( tab ) => tab . key === homePath ) ) {
184185 newTabs . push ( homeTab ) ;
185186 }
186187 }
187-
188+
188189 // 如果当前激活的tab不在保留的tab中,需要激活目标tab
189- const newActiveKey = newTabs . some ( tab => tab . key === activeKey ) ? activeKey : targetKey ;
190- set ( {
190+ const newActiveKey = newTabs . some ( ( tab ) => tab . key === activeKey ) ? activeKey : targetKey ;
191+ set ( {
191192 tabs : newTabs ,
192- activeKey : newActiveKey
193+ activeKey : newActiveKey ,
193194 } ) ;
194195 return newActiveKey ;
195196 }
@@ -198,31 +199,43 @@ export const useTabStore = create<TabStore>()(
198199
199200 closeAllTabs : ( homePath ?: string ) => {
200201 const { tabs } = get ( ) ;
201-
202+
202203 if ( homePath ) {
203204 // 保留homePath的tab
204205 const homeTab = tabs . find ( ( tab ) => tab . key === homePath ) ;
205206 if ( homeTab ) {
206- set ( {
207- tabs : [ homeTab ] ,
208- activeKey : homePath
207+ set ( {
208+ tabs : [ homeTab ] ,
209+ activeKey : homePath ,
209210 } ) ;
210211 return homePath ;
211212 }
212213 }
213-
214+
214215 // 如果没有homePath或找不到homeTab,清空所有tabs
215216 set ( { tabs : [ ] , activeKey : '' } ) ;
216217 return '' ;
217218 } ,
218219
219220 reloadTab : ( targetKey : string ) => {
220- // 这里可以通过重新渲染组件来实现重新加载
221- // 暂时只是重新设置activeKey来触发重新渲染
222- const { activeKey } = get ( ) ;
223- if ( targetKey === activeKey ) {
224- set ( { activeKey : '' } ) ;
225- setTimeout ( ( ) => set ( { activeKey : targetKey } ) , 0 ) ;
221+ const { tabs } = get ( ) ;
222+
223+ // 1. 清除 KeepAlive 缓存
224+ if ( typeof window !== 'undefined' && ( window as any ) . __keepAliveClearCache ) {
225+ ( window as any ) . __keepAliveClearCache ( targetKey ) ;
226+ }
227+
228+ // 2. 更新 tab 的 reloadKey,强制重新挂载组件
229+ const newTabs = tabs . map ( ( tab ) => ( tab . key === targetKey ? { ...tab , reloadKey : Date . now ( ) } : tab ) ) ;
230+
231+ set ( { tabs : newTabs } ) ;
232+
233+ // 3. 触发页面重新渲染(如果是当前激活的 tab)
234+ // 通过重新导航到同一路径来触发 TanStack Router 的重新加载
235+ if ( window . location . pathname === targetKey ) {
236+ // 使用 window.location.reload() 会刷新整个页面,这里我们不需要
237+ // TanStack Router 会自动处理组件的重新渲染
238+ console . log ( '🔄 重新加载 tab:' , targetKey ) ;
226239 }
227240 } ,
228241
@@ -255,6 +268,6 @@ export const useTabStore = create<TabStore>()(
255268 {
256269 name : 'tab-store' ,
257270 getStorage : ( ) => localStorage ,
258- } as PersistOptions < TabStore > ,
259- ) ,
271+ } as PersistOptions < TabStore >
272+ )
260273) ;
0 commit comments