DialogBox.vue 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. <script lang="ts" setup>
  2. type DialogType = 'success' | 'error' | 'info'
  3. interface Props {
  4. /** 是否显示对话框 */
  5. show?: boolean
  6. /** 对话框类型 */
  7. type?: DialogType
  8. /** 确认按钮文本 */
  9. confirmText?: string
  10. /** 取消按钮文本 */
  11. cancelText?: string
  12. /** 图标大小 */
  13. iconSize?: string
  14. /** 主要消息内容 */
  15. message?: string
  16. /** 提示信息 */
  17. tip?: string
  18. /** 是否显示确认按钮 */
  19. showConfirm?: boolean
  20. /** 是否显示取消按钮 */
  21. showCancel?: boolean
  22. /** 是否显示提示信息 */
  23. showTip?: boolean
  24. /** 点击遮罩是否关闭 */
  25. closeOnClickOverlay?: boolean
  26. }
  27. interface Emits {
  28. /** 更新显示状态 */
  29. (e: 'update:show', value: boolean): void
  30. /** 确认按钮点击事件 */
  31. (e: 'confirm'): void
  32. /** 取消按钮点击事件 */
  33. (e: 'cancel'): void
  34. /** 对话框关闭事件 */
  35. (e: 'close'): void
  36. }
  37. const props = withDefaults(defineProps<Props>(), {
  38. show: false,
  39. type: 'info',
  40. confirmText: '确认',
  41. cancelText: '取消',
  42. iconSize: '120rpx',
  43. message: '',
  44. tip: '',
  45. showConfirm: true,
  46. showCancel: false,
  47. showTip: false,
  48. closeOnClickOverlay: true,
  49. })
  50. const emit = defineEmits<Emits>()
  51. // 根据类型获取图标路径
  52. const iconSrc = computed(() => {
  53. const iconMap = {
  54. success: '/static/icons/icon-success.png',
  55. error: '/static/icons/icon-error.png',
  56. info: '/static/icons/icon-info.png',
  57. }
  58. return iconMap[props.type]
  59. })
  60. // 处理遮罩点击
  61. function handleOverlayClick() {
  62. if (props.closeOnClickOverlay) {
  63. handleClose()
  64. }
  65. }
  66. // 处理关闭
  67. function handleClose() {
  68. emit('update:show', false)
  69. emit('close')
  70. }
  71. // 处理确认按钮点击
  72. function handleConfirm() {
  73. emit('confirm')
  74. handleClose()
  75. }
  76. // 处理取消按钮点击
  77. function handleCancel() {
  78. emit('cancel')
  79. handleClose()
  80. }
  81. </script>
  82. <template>
  83. <wd-overlay :show="props.show" @click="handleOverlayClick">
  84. <view class="wrapper">
  85. <view class="rounded-24rpx bg-white p-40rpx text-center" @click.stop>
  86. <image
  87. :src="iconSrc"
  88. :style="{ width: props.iconSize, height: props.iconSize }"
  89. />
  90. <view class="pb-58rpx pt-34rpx text-center text-32rpx">
  91. {{ props.message }}
  92. </view>
  93. <!-- 按钮区域 -->
  94. <view class="button-container">
  95. <!-- 只有确认按钮时居中显示 -->
  96. <wd-button
  97. v-if="props.showConfirm && !props.showCancel"
  98. plain
  99. block
  100. @click="handleConfirm"
  101. >
  102. {{ props.confirmText }}
  103. </wd-button>
  104. <!-- 有取消按钮时并排显示 -->
  105. <template v-if="props.showConfirm && props.showCancel">
  106. <wd-button
  107. class="button-half"
  108. plain
  109. block
  110. custom-class="text-#333! border-#333!"
  111. @click="handleCancel"
  112. >
  113. {{ props.cancelText }}
  114. </wd-button>
  115. <wd-button
  116. plain
  117. block
  118. class="button-half"
  119. type="primary"
  120. @click="handleConfirm"
  121. >
  122. {{ props.confirmText }}
  123. </wd-button>
  124. </template>
  125. </view>
  126. <view v-if="props.showTip && props.tip" class="mt-20rpx text-24rpx text-gray-500">
  127. {{ props.tip }}
  128. </view>
  129. </view>
  130. </view>
  131. </wd-overlay>
  132. </template>
  133. <style lang="scss" scoped>
  134. .wrapper {
  135. display: flex;
  136. align-items: center;
  137. justify-content: center;
  138. height: 100%;
  139. padding: 0 24rpx;
  140. }
  141. .button-container {
  142. display: flex;
  143. justify-content: center;
  144. gap: 20rpx;
  145. .button-half {
  146. flex: 1;
  147. }
  148. }
  149. </style>