CNCEC_APP/uni_modules/uview-pro/libs/hooks/useToast.ts

116 lines
4.0 KiB
TypeScript
Raw Normal View History

2026-03-25 14:54:15 +08:00
import {
U_TOAST_EVENT_HIDE,
U_TOAST_EVENT_SHOW,
U_TOAST_GLOBAL_EVENT_HIDE,
U_TOAST_GLOBAL_EVENT_SHOW,
getEventWithCurrentPage,
type ToastPayload
} from '../../components/u-toast/service';
import type { ThemeType } from '../../types/global';
export type UseToastShowOptions = ToastPayload;
export type UseToast = {
/**
* toast
* - show('文本')
* - show({ title, type, duration, ... })
*/
show: (titleOrOptions: string | UseToastShowOptions) => void;
/** 关闭 toast */
close: () => void;
/** 成功 */
success: (titleOrOptions: string | UseToastShowOptions) => void;
/** 错误 */
error: (titleOrOptions: string | UseToastShowOptions) => void;
/** 警告 */
warning: (titleOrOptions: string | UseToastShowOptions) => void;
/** 信息 */
info: (titleOrOptions: string | UseToastShowOptions) => void;
/** 加载中(默认常驻,需 close 关闭) */
loading: (titleOrOptions: string | UseToastShowOptions) => void;
};
export type UseToastOptions = {
/** 是否使用全局根部 <u-toast global />,默认 true为 false 时走页面级 <u-toast /> */
global?: boolean;
/** 是否使用页面级 <u-toast page /> 或某个页面的 <u-toast page="pageId" /> */
page?: boolean | string;
};
function normalize(titleOrOptions: string | UseToastShowOptions): UseToastShowOptions {
if (typeof titleOrOptions === 'string') return { title: titleOrOptions };
return titleOrOptions || {};
}
function getPage(optionsOrGlobal: UseToastOptions | boolean): string {
if (typeof optionsOrGlobal === 'boolean') {
return '';
}
if (optionsOrGlobal.page && typeof optionsOrGlobal.page === 'string' && optionsOrGlobal.page !== '') {
return optionsOrGlobal.page;
}
return '';
}
/**
* Toast
* @description / <u-toast global /> <u-toast page /> ref
*
*
* - useToast() / useToast(true) / useToast({ global: true })
* - useToast(false) / useToast({ page: true }) / useToast({ page: 'pageId' }) pageId <u-toast page="pageId" /> page
*/
export function useToast(optionsOrGlobal: UseToastOptions | boolean = true): UseToast {
const isGlobal = typeof optionsOrGlobal === 'boolean' ? optionsOrGlobal === true : !!optionsOrGlobal.global;
const isPage = typeof optionsOrGlobal === 'boolean' ? optionsOrGlobal === false : !!optionsOrGlobal.page;
const showEvent = isGlobal
? U_TOAST_GLOBAL_EVENT_SHOW
: isPage
? getEventWithCurrentPage(U_TOAST_EVENT_SHOW, getPage(optionsOrGlobal))
: '';
const hideEvent = isGlobal
? U_TOAST_GLOBAL_EVENT_HIDE
: isPage
? getEventWithCurrentPage(U_TOAST_EVENT_HIDE, getPage(optionsOrGlobal))
: '';
function emitShow(payload: UseToastShowOptions) {
if (showEvent) {
uni?.$emit && uni.$emit(showEvent, payload);
}
}
function emitHide() {
if (hideEvent) {
uni?.$emit && uni.$emit(hideEvent);
}
}
function show(titleOrOptions: string | UseToastShowOptions) {
emitShow(normalize(titleOrOptions));
}
function close() {
emitHide();
}
function withType(type: ThemeType, titleOrOptions: string | UseToastShowOptions) {
const options = normalize(titleOrOptions);
emitShow({ ...options, type });
}
return {
show,
close,
success: (v: any) => withType('success', v),
error: (v: any) => withType('error', v),
warning: (v: any) => withType('warning', v),
info: (v: any) => withType('info', v),
loading: (v: any) => {
const options = normalize(v);
// loading 通常需要常驻,除非用户显式传 duration
emitShow({ ...options, loading: true, duration: options.duration ?? 0 });
}
};
}