feat(状态管理): 扩展 Redux store 支持标签页状态管理

- 新增 tabs 状态字段到 GlobalState
- 实现标签页增删改查的 reducer 逻辑
- 支持添加标签、移除标签、设置激活标签
- 支持关闭左侧、右侧、其他标签的批量操作
- 自动处理标签关闭后的激活状态切换
This commit is contained in:
gaoziman 2025-11-07 22:35:47 +08:00
parent 3501ac55c9
commit e8cacc2c7a

View File

@ -1,4 +1,6 @@
import defaultSettings from '../settings.json'; import defaultSettings from '../settings.json';
import { TabItem, TabsState } from '@/types/tabs';
export interface GlobalState { export interface GlobalState {
settings?: typeof defaultSettings; settings?: typeof defaultSettings;
userInfo?: { userInfo?: {
@ -11,6 +13,7 @@ export interface GlobalState {
permissions: Record<string, string[]>; permissions: Record<string, string[]>;
}; };
userLoading?: boolean; userLoading?: boolean;
tabs?: TabsState;
} }
const initialState: GlobalState = { const initialState: GlobalState = {
@ -18,6 +21,10 @@ const initialState: GlobalState = {
userInfo: { userInfo: {
permissions: {}, permissions: {},
}, },
tabs: {
activeKey: '',
tabs: [],
},
}; };
export default function store(state = initialState, action) { export default function store(state = initialState, action) {
@ -37,6 +44,134 @@ export default function store(state = initialState, action) {
userInfo, userInfo,
}; };
} }
// 添加标签页
case 'tabs/addTab': {
const newTab: TabItem = action.payload;
const existingTab = state.tabs.tabs.find((tab) => tab.key === newTab.key);
if (existingTab) {
// 如果标签已存在,只更新激活状态
return {
...state,
tabs: {
...state.tabs,
activeKey: newTab.key,
},
};
}
// 添加新标签
return {
...state,
tabs: {
activeKey: newTab.key,
tabs: [...state.tabs.tabs, newTab],
},
};
}
// 移除标签页
case 'tabs/removeTab': {
const targetKey: string = action.payload;
const { tabs, activeKey } = state.tabs;
const targetIndex = tabs.findIndex((tab) => tab.key === targetKey);
if (targetIndex === -1) {
return state;
}
const newTabs = tabs.filter((tab) => tab.key !== targetKey);
let newActiveKey = activeKey;
// 如果关闭的是当前激活的标签,需要激活相邻标签
if (activeKey === targetKey && newTabs.length > 0) {
// 优先激活右侧标签,如果没有则激活左侧
if (targetIndex < tabs.length - 1) {
newActiveKey = tabs[targetIndex + 1].key;
} else {
newActiveKey = tabs[targetIndex - 1].key;
}
}
return {
...state,
tabs: {
activeKey: newActiveKey,
tabs: newTabs,
},
};
}
// 设置激活的标签页
case 'tabs/setActiveTab': {
const activeKey: string = action.payload;
return {
...state,
tabs: {
...state.tabs,
activeKey,
},
};
}
// 关闭左侧标签页
case 'tabs/closeLeftTabs': {
const targetKey: string = action.payload;
const targetIndex = state.tabs.tabs.findIndex(
(tab) => tab.key === targetKey
);
if (targetIndex <= 0) {
return state;
}
const newTabs = state.tabs.tabs.filter((tab, index) => {
return index >= targetIndex || !tab.closable;
});
return {
...state,
tabs: {
...state.tabs,
tabs: newTabs,
},
};
}
// 关闭右侧标签页
case 'tabs/closeRightTabs': {
const targetKey: string = action.payload;
const targetIndex = state.tabs.tabs.findIndex(
(tab) => tab.key === targetKey
);
if (targetIndex === -1 || targetIndex === state.tabs.tabs.length - 1) {
return state;
}
const newTabs = state.tabs.tabs.filter((tab, index) => {
return index <= targetIndex || !tab.closable;
});
return {
...state,
tabs: {
...state.tabs,
tabs: newTabs,
},
};
}
// 关闭其他标签页
case 'tabs/closeOtherTabs': {
const targetKey: string = action.payload;
const newTabs = state.tabs.tabs.filter((tab) => {
return tab.key === targetKey || !tab.closable;
});
return {
...state,
tabs: {
activeKey: targetKey,
tabs: newTabs,
},
};
}
default: default:
return state; return state;
} }