toast.ts 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. /**
  2. * toast 弹窗组件
  3. * 支持 success/error/warning/info 四种状态
  4. * 可配置 duration, position 等参数
  5. */
  6. type ToastType = 'success' | 'error' | 'warning' | 'info'
  7. interface ToastOptions {
  8. type?: ToastType
  9. duration?: number
  10. position?: 'top' | 'middle' | 'bottom'
  11. icon?: 'success' | 'error' | 'none' | 'loading' | 'fail' | 'exception'
  12. message: string
  13. }
  14. export function showToast(options: ToastOptions | string) {
  15. const defaultOptions: ToastOptions = {
  16. type: 'info',
  17. duration: 2000,
  18. position: 'middle',
  19. message: '',
  20. }
  21. const mergedOptions
  22. = typeof options === 'string'
  23. ? { ...defaultOptions, message: options }
  24. : { ...defaultOptions, ...options }
  25. // #ifdef APP-PLUS
  26. // 关闭上一次的提示
  27. plus.nativeUI.closeToast()
  28. // 使用 plus.nativeUI.toast 实现
  29. // 映射 position 到 plus.nativeUI.toast 支持的格式
  30. const positionMap: Record<ToastOptions['position'], { vertical: string, horizontal: string }> = {
  31. top: { vertical: 'top', horizontal: 'center' },
  32. middle: { vertical: 'center', horizontal: 'center' },
  33. bottom: { vertical: 'bottom', horizontal: 'center' },
  34. }
  35. // 映射图标类型
  36. const plusIconMap: Record<
  37. ToastType,
  38. 'success' | 'error' | 'none' | 'loading' | 'fail' | 'exception'
  39. > = {
  40. success: 'success',
  41. error: 'error',
  42. warning: 'fail',
  43. info: 'none',
  44. }
  45. // 安卓平台添加适当偏移,iOS保持默认
  46. const platform = plus.os.name
  47. const verticalOffset = platform === 'Android' ? '50%' : 'center'
  48. // 构造 ToastStyles 配置项
  49. const toastOptions: any = {
  50. duration: mergedOptions.duration >= 3000 ? 'long' : 'short',
  51. ...positionMap[mergedOptions.position],
  52. align: 'center', // 文字居中对齐
  53. verticalAlign: verticalOffset, // 垂直位置补偿
  54. background: 'rgba(0,0,0,0.7)',
  55. type: 'richtext',
  56. }
  57. // 如果有图标配置,则添加图标
  58. if (mergedOptions.icon || plusIconMap[mergedOptions.type]) {
  59. toastOptions.icon = mergedOptions.icon || plusIconMap[mergedOptions.type]
  60. }
  61. plus.nativeUI.toast(`<font style=\"color:#fff;font-size:16px;\">${mergedOptions.message}</font>`, toastOptions)
  62. return
  63. // #endif
  64. // #ifndef APP-PLUS
  65. // 映射position到uniapp支持的格式
  66. const uniPositionMap: Record<ToastOptions['position'], 'top' | 'bottom' | 'center'> = {
  67. top: 'top',
  68. middle: 'center',
  69. bottom: 'bottom',
  70. }
  71. // 映射图标类型
  72. const uniIconMap: Record<
  73. ToastType,
  74. 'success' | 'error' | 'none' | 'loading' | 'fail' | 'exception'
  75. > = {
  76. success: 'success',
  77. error: 'error',
  78. warning: 'fail',
  79. info: 'none',
  80. }
  81. // 调用uni.showToast显示提示
  82. uni.showToast({
  83. title: mergedOptions.message,
  84. duration: mergedOptions.duration,
  85. position: uniPositionMap[mergedOptions.position],
  86. icon: mergedOptions.icon || uniIconMap[mergedOptions.type],
  87. mask: true,
  88. })
  89. // #endif
  90. }
  91. export const toast = {
  92. success: (message: string, options?: Omit<ToastOptions, 'type'>) =>
  93. showToast({ ...options, type: 'success', message }),
  94. error: (message: string, options?: Omit<ToastOptions, 'type'>) =>
  95. showToast({ ...options, type: 'error', message }),
  96. warning: (message: string, options?: Omit<ToastOptions, 'type'>) =>
  97. showToast({ ...options, type: 'warning', message }),
  98. info: (message: string, options?: Omit<ToastOptions, 'type'>) =>
  99. showToast({ ...options, type: 'info', message }),
  100. }