import {createStore} from 'zustand/vanilla'; type State = { activeKey: string; tabList: { key: string; url: string; label: string; }[]; }; type DispatchOptions = | {type: 'ADD'; payload: State['tabList'][0]} | {type: 'REMOVE'; payload: string} | {type: 'REMOVE_OTHER'; payload: string} | {type: 'REMOVE_RIGHT'; payload: string} | {type: 'CLEAR'} | {type: 'SORT'; payload: State['tabList']}; type Action = { setActiveKey: (key: string | ((prev: string) => string)) => void; dispatch: (value: DispatchOptions) => void; }; const defaultTab: State['tabList'][0] = { key: '-1', url: '/main', label: '首页', }; function reducer( state: State['tabList'], action: DispatchOptions, ): State['tabList'] { const {type} = action; switch (type) { case 'ADD': { const {payload} = action; const exist = state.find(val => val.key === payload.key); if (exist) { return state; } return [...state, payload]; } case 'REMOVE': { const {payload} = action; const idx = state.findIndex(val => val.key === payload); if (idx < 0) return state; const nextState = [...state]; nextState.splice(idx, 1); return nextState; } case 'REMOVE_OTHER': { const {payload} = action; const idx = state.findIndex(val => val.key === payload); if (idx < 0) return state; return [{...defaultTab}, {...state[idx]}]; } case 'REMOVE_RIGHT': { const {payload} = action; const idx = state.findIndex(val => val.key === payload); if (idx < 0) return state; const {length} = state; const nextState = [...state]; nextState.splice(idx + 1, length - idx - 1); return nextState; } case 'CLEAR': { return [{...defaultTab}]; } case 'SORT': return action.payload; default: return state; } } export const tabStore = createStore(function (set) { return { activeKey: '-1', tabList: [defaultTab], setActiveKey(key) { set(function (prev) { return {activeKey: typeof key === 'string' ? key : key(prev.activeKey)}; }); }, dispatch(value) { set(function (prev) { let nextActiveKey = prev.activeKey; const result = reducer(prev.tabList, value); switch (value.type) { case 'ADD': nextActiveKey = value.payload.key; break; case 'REMOVE': { const idx = prev.tabList.findIndex( val => val.key === value.payload, ); idx >= 0 && (nextActiveKey = prev.tabList[idx].key); break; } case 'REMOVE_OTHER': nextActiveKey = value.payload; break; case 'REMOVE_RIGHT': { result.findIndex(val => val.key === prev.activeKey) < 0 && (nextActiveKey = value.payload); break; } case 'CLEAR': nextActiveKey = '-1'; break; case 'SORT': { break; } } return {tabList: result, activeKey: nextActiveKey}; }); }, }; });