import { ref, Ref, DeepReadonly, readonly } from 'vue'; export type ToggleParamType = string | number | boolean | undefined | null; export interface ToggleReturn { state: DeepReadonly<Ref<boolean>>; toggle: (next?: boolean) => void; setDefault: () => void; setRight: () => void; } export interface ITwoType<T extends ToggleParamType = ToggleParamType, U extends ToggleParamType = ToggleParamType> extends Omit<ToggleReturn, 'state' | 'toggle'> { state: DeepReadonly<Ref<T | U>>; toggle: (next?: T | U) => void; } export interface IToggle { (): ToggleReturn; (defaultValue: boolean): ToggleReturn; <T extends ToggleParamType = ToggleParamType, U extends ToggleParamType = ToggleParamType>(defaultValue: T, resetValue?: U): ITwoType<T, U>; } export const useToggle: IToggle = <T extends ToggleParamType = ToggleParamType, U extends ToggleParamType = ToggleParamType>(defaultValue: T = false as T, reverseValue?: U) => { const state = ref(defaultValue) as Ref<T | U>; const reverseTo = (reverseValue === undefined ? !defaultValue : reverseValue) as T | U; const toggle = (next?: T | U) => { if (next !== undefined) { state.value = next; } else { state.value = state.value === defaultValue ? reverseTo : defaultValue; } }; const setDefault = () => { state.value = defaultValue; }; const setRight = () => { state.value = reverseTo; }; return { state: readonly(state), setDefault, setRight, toggle, }; }; 扩展阅读 toggle切换 useToggle