@@ -65,54 +65,145 @@ const TabBar: React.FC<TabBarProps> = ({ className }) => {
6565 // 初始化标记,避免重复初始化
6666 const isInitializedRef = useRef ( false ) ;
6767
68- // 确保 homePath 对应的 tab 永远在第一个显示且固定(仅在初始化时执行)
68+ // 页面刷新时的状态恢复逻辑
6969 React . useEffect ( ( ) => {
70- // 只有在没有tab且有菜单数据且有homePath且未初始化时才执行
71- if ( ! isInitializedRef . current && tabs . length === 0 && menus . length > 0 && homePath ) {
70+ // 只有在有菜单数据且有homePath且未初始化时才执行
71+ if ( ! isInitializedRef . current && menus . length > 0 && homePath ) {
7272 isInitializedRef . current = true ;
7373
74- // 首先创建homePath的tab(第一个位置)
75- const homeRoute = findRouteByPath ( homePath ) ;
76- if ( homeRoute ?. path ) {
77- const homeTabItem : TabItem = {
78- key : homePath ,
79- label : homeRoute . meta ?. title || homePath ,
80- icon : homeRoute . meta ?. icon ,
81- path : homePath ,
82- closable : false , // 第一个tab不可关闭
83- route : homeRoute ,
84- } ;
74+ // 如果当前没有tabs,说明是首次加载,需要初始化
75+ if ( tabs . length === 0 ) {
76+ // 首先创建homePath的tab(第一个位置)
77+ const homeRoute = findRouteByPath ( homePath ) ;
78+ if ( homeRoute ?. path ) {
79+ const homeTabItem : TabItem = {
80+ key : homePath ,
81+ label : homeRoute . meta ?. title || homePath ,
82+ icon : homeRoute . meta ?. icon ,
83+ path : homePath ,
84+ closable : false , // 第一个tab不可关闭
85+ route : homeRoute ,
86+ } ;
8587
86- // 使用头插入,激活 homePath(登录后默认激活首页 )
87- addTab ( homeTabItem , { insertAt : 'head' , activate : true } ) ;
88- }
88+ // 使用头插入,但不激活(根据当前路径决定激活哪个 )
89+ addTab ( homeTabItem , { insertAt : 'head' , activate : false } ) ;
90+ }
8991
90- // 然后检查当前路径是否有效(在菜单中存在)
91- const currentRoute = findRouteByPath ( pathname ) ;
92+ // 然后检查当前路径是否有效(在菜单中存在)
93+ const currentRoute = findRouteByPath ( pathname ) ;
9294
93- if ( currentRoute ?. path && pathname !== homePath ) {
94- // 如果当前路径有效且不是homePath,创建对应的tab
95- const currentTabItem : TabItem = {
96- key : pathname ,
97- label : currentRoute . meta ?. title || pathname ,
98- icon : currentRoute . meta ?. icon ,
99- path : pathname ,
100- closable : true ,
101- route : currentRoute ,
102- } ;
95+ if ( currentRoute ?. path && pathname !== homePath ) {
96+ // 如果当前路径有效且不是homePath,创建对应的tab
97+ const currentTabItem : TabItem = {
98+ key : pathname ,
99+ label : currentRoute . meta ?. title || pathname ,
100+ icon : currentRoute . meta ?. icon ,
101+ path : pathname ,
102+ closable : true ,
103+ route : currentRoute ,
104+ } ;
103105
104- // 使用尾插入,激活当前页面
105- addTab ( currentTabItem , { insertAt : 'tail' , activate : true } ) ;
106- } else if ( pathname !== homePath ) {
107- // 如果当前路径无效且不是homePath,跳转到homePath
108- navigate ( homePath , { replace : true } ) ;
106+ // 使用尾插入,激活当前页面
107+ addTab ( currentTabItem , { insertAt : 'tail' , activate : true } ) ;
108+ } else if ( pathname === homePath ) {
109+ // 如果当前路径就是homePath,激活homePath的tab
110+ setActiveKey ( homePath ) ;
111+ } else {
112+ // 如果当前路径无效且不是homePath,跳转到homePath
113+ navigate ( homePath , { replace : true } ) ;
114+ }
115+ } else {
116+ // 页面刷新时,tabs已经存在,需要确保状态正确
117+ // 1. 确保homePath的tab存在且不可关闭
118+ const homeTab = tabs . find ( tab => tab . key === homePath ) ;
119+ if ( homeTab ) {
120+ // 确保homePath的tab不可关闭
121+ if ( homeTab . closable ) {
122+ const updatedTabs = tabs . map ( tab =>
123+ tab . key === homePath ? { ...tab , closable : false } : tab
124+ ) ;
125+ setTabs ( updatedTabs , activeKey ) ;
126+ }
127+ } else {
128+ // 如果homePath的tab不存在,需要添加
129+ const homeRoute = findRouteByPath ( homePath ) ;
130+ if ( homeRoute ?. path ) {
131+ const homeTabItem : TabItem = {
132+ key : homePath ,
133+ label : homeRoute . meta ?. title || homePath ,
134+ icon : homeRoute . meta ?. icon ,
135+ path : homePath ,
136+ closable : false ,
137+ route : homeRoute ,
138+ } ;
139+ addTab ( homeTabItem , { insertAt : 'head' , activate : false } ) ;
140+ }
141+ }
142+
143+ // 2. 确保当前路径对应的tab存在并激活
144+ const currentTab = tabs . find ( tab => tab . key === pathname ) ;
145+ if ( ! currentTab && pathname !== homePath ) {
146+ const currentRoute = findRouteByPath ( pathname ) ;
147+ if ( currentRoute ?. path ) {
148+ const currentTabItem : TabItem = {
149+ key : pathname ,
150+ label : currentRoute . meta ?. title || pathname ,
151+ icon : currentRoute . meta ?. icon ,
152+ path : pathname ,
153+ closable : true ,
154+ route : currentRoute ,
155+ } ;
156+ addTab ( currentTabItem , { insertAt : 'tail' , activate : true } ) ;
157+ }
158+ } else if ( currentTab ) {
159+ // 如果当前路径的tab存在,激活它
160+ setActiveKey ( pathname ) ;
161+ } else if ( pathname === homePath ) {
162+ // 如果当前路径就是homePath,确保激活homePath的tab
163+ setActiveKey ( homePath ) ;
164+ }
165+
166+ // 3. 确保homePath的tab在第一个位置
167+ const homeTabIndex = tabs . findIndex ( tab => tab . key === homePath ) ;
168+ if ( homeTabIndex > 0 ) {
169+ const homeTab = tabs [ homeTabIndex ] ;
170+ const otherTabs = tabs . filter ( tab => tab . key !== homePath ) ;
171+ const newTabs = [ homeTab , ...otherTabs ] ;
172+ setTabs ( newTabs , activeKey ) ;
173+ }
109174 }
110175 }
111- } , [ menus , homePath , findRouteByPath , navigate , tabs . length , pathname ] ) ; // 重新添加必要的依赖
176+ } , [ menus , homePath , findRouteByPath , navigate , tabs , activeKey , addTab , setActiveKey , setTabs , pathname ] ) ;
112177
113- // 确保 homePath 对应的 tab 始终存在(即使在其他tab被添加后)
178+ // 处理路径变化时的tab激活逻辑
114179 React . useEffect ( ( ) => {
115- if ( menus . length > 0 && homePath && tabs . length > 0 ) {
180+ // 只有在初始化完成后才处理路径变化
181+ if ( isInitializedRef . current && menus . length > 0 && homePath && tabs . length > 0 ) {
182+ // 确保当前路径对应的tab被激活
183+ const currentTab = tabs . find ( tab => tab . key === pathname ) ;
184+ if ( currentTab && activeKey !== pathname ) {
185+ setActiveKey ( pathname ) ;
186+ } else if ( ! currentTab && pathname !== homePath ) {
187+ // 如果当前路径的tab不存在且不是homePath,创建并激活它
188+ const currentRoute = findRouteByPath ( pathname ) ;
189+ if ( currentRoute ?. path ) {
190+ const currentTabItem : TabItem = {
191+ key : pathname ,
192+ label : currentRoute . meta ?. title || pathname ,
193+ icon : currentRoute . meta ?. icon ,
194+ path : pathname ,
195+ closable : true ,
196+ route : currentRoute ,
197+ } ;
198+ addTab ( currentTabItem , { insertAt : 'tail' , activate : true } ) ;
199+ }
200+ }
201+ }
202+ } , [ pathname , tabs , activeKey , setActiveKey , menus , homePath , findRouteByPath , addTab ] ) ;
203+
204+ // 确保 homePath 对应的 tab 始终存在且不可关闭(在tabs变化时检查)
205+ React . useEffect ( ( ) => {
206+ if ( menus . length > 0 && homePath && tabs . length > 0 && isInitializedRef . current ) {
116207 const homeRoute = findRouteByPath ( homePath ) ;
117208 const homeTabExists = tabs . some ( ( tab ) => tab . key === homePath ) ;
118209
@@ -144,50 +235,34 @@ const TabBar: React.FC<TabBarProps> = ({ className }) => {
144235 }
145236 }
146237 }
147- } , [ menus , homePath , findRouteByPath ] ) ; // 移除tabs和activeKey依赖,减少不必要的重新排序
238+ } , [ menus , homePath , findRouteByPath , tabs , activeKey , addTab , setTabs ] ) ;
148239
149240
150- // 合并路径变化处理和空tabs处理逻辑
151- const pathAndTabsHandler = useMemo ( ( ) => {
152- return ( ) => {
153- // 如果正在关闭tab,跳过执行
154- if ( isClosingTabRef . current ) {
155- isClosingTabRef . current = false ;
156- return ;
157- }
241+ // 处理路径变化时的tab管理逻辑(仅在初始化完成后执行)
242+ React . useEffect ( ( ) => {
243+ // 如果正在关闭tab,跳过执行
244+ if ( isClosingTabRef . current ) {
245+ isClosingTabRef . current = false ;
246+ return ;
247+ }
158248
159- if ( ! pathname || pathname === '/login' ) return ;
249+ // 只有在初始化完成后才处理路径变化
250+ if ( ! isInitializedRef . current || ! menus . length || ! homePath ) return ;
160251
161- // 如果当前没有tabs,说明是关闭所有tabs后的情况,需要跳转到首页
162- if ( tabs . length === 0 ) {
163- if ( homePath && pathname !== homePath ) {
164- navigate ( homePath , { replace : true } ) ;
165- }
166- return ;
167- }
252+ if ( ! pathname || pathname === '/login' ) return ;
168253
169- // 如果tabs存在但只有一个且是homePath,且当前路径不是homePath,则添加新tab
170- if ( tabs . length === 1 && tabs [ 0 ] . key === homePath && pathname !== homePath ) {
171- const route = findRouteByPath ( pathname ) ;
172- if ( route ) {
173- const tabItem : TabItem = {
174- key : pathname ,
175- label : route . meta ?. title || pathname ,
176- icon : route . meta ?. icon ,
177- path : pathname ,
178- closable : true ,
179- route,
180- } ;
181- useTabStore . getState ( ) . addTab ( tabItem ) ;
182- }
183- return ;
254+ // 如果当前没有tabs,说明是关闭所有tabs后的情况,需要跳转到首页
255+ if ( tabs . length === 0 ) {
256+ if ( homePath && pathname !== homePath ) {
257+ navigate ( homePath , { replace : true } ) ;
184258 }
259+ return ;
260+ }
185261
186- // 如果tabs存在且超过1个,检查当前路径对应的tab
187- if ( tabs . length > 1 ) {
188- const route = findRouteByPath ( pathname ) ;
189- if ( ! route ) return ;
190-
262+ // 如果tabs存在但只有一个且是homePath,且当前路径不是homePath,则添加新tab
263+ if ( tabs . length === 1 && tabs [ 0 ] . key === homePath && pathname !== homePath ) {
264+ const route = findRouteByPath ( pathname ) ;
265+ if ( route ) {
191266 const tabItem : TabItem = {
192267 key : pathname ,
193268 label : route . meta ?. title || pathname ,
@@ -196,32 +271,39 @@ const TabBar: React.FC<TabBarProps> = ({ className }) => {
196271 closable : true ,
197272 route,
198273 } ;
199-
200- // 检查tab是否已存在
201- const existingTab = tabs . find ( ( tab ) => tab . key === pathname ) ;
202- if ( ! existingTab ) {
203- // 新tab,添加到store
204- useTabStore . getState ( ) . addTab ( tabItem ) ;
205- } else {
206- // tab已存在,只激活它
207- setActiveKey ( pathname ) ;
208- }
274+ useTabStore . getState ( ) . addTab ( tabItem ) ;
209275 }
210- } ;
211- } , [ pathname , tabs , homePath , findRouteByPath , setActiveKey , navigate ] ) ;
276+ return ;
277+ }
212278
213- // 合并路径变化和空tabs处理
214- React . useEffect ( ( ) => {
215- pathAndTabsHandler ( ) ;
216- } , [ pathAndTabsHandler ] ) ;
279+ // 如果tabs存在且超过1个,检查当前路径对应的tab
280+ if ( tabs . length > 1 ) {
281+ const route = findRouteByPath ( pathname ) ;
282+ if ( ! route ) return ;
283+
284+ const tabItem : TabItem = {
285+ key : pathname ,
286+ label : route . meta ?. title || pathname ,
287+ icon : route . meta ?. icon ,
288+ path : pathname ,
289+ closable : true ,
290+ route,
291+ } ;
217292
218- // 监听用户退出登录和页面刷新事件
219- React . useEffect ( ( ) => {
220- const handleBeforeUnload = ( ) => {
221- // 页面刷新或关闭时清空所有tab
222- resetTabs ( ) ;
223- } ;
293+ // 检查tab是否已存在
294+ const existingTab = tabs . find ( ( tab ) => tab . key === pathname ) ;
295+ if ( ! existingTab ) {
296+ // 新tab,添加到store
297+ useTabStore . getState ( ) . addTab ( tabItem ) ;
298+ } else {
299+ // tab已存在,只激活它
300+ setActiveKey ( pathname ) ;
301+ }
302+ }
303+ } , [ pathname , tabs , homePath , findRouteByPath , setActiveKey , navigate , menus ] ) ;
224304
305+ // 监听用户退出登录事件(不监听页面刷新)
306+ React . useEffect ( ( ) => {
225307 const handleStorageChange = ( e : StorageEvent ) => {
226308 // 监听 localStorage 变化,检测用户登录状态变化
227309 if ( e . key === 'user-storage' ) {
@@ -237,11 +319,9 @@ const TabBar: React.FC<TabBarProps> = ({ className }) => {
237319 }
238320 } ;
239321
240- window . addEventListener ( 'beforeunload' , handleBeforeUnload ) ;
241322 window . addEventListener ( 'storage' , handleStorageChange ) ;
242323
243324 return ( ) => {
244- window . removeEventListener ( 'beforeunload' , handleBeforeUnload ) ;
245325 window . removeEventListener ( 'storage' , handleStorageChange ) ;
246326 } ;
247327 } , [ resetTabs ] ) ;
0 commit comments