|
|
@@ -7,38 +7,83 @@
|
|
|
<div class="dialog-title">{{ title }}</div>
|
|
|
<div class="dialog-message">{{ message }}</div>
|
|
|
|
|
|
- <van-button
|
|
|
- type="primary"
|
|
|
- block
|
|
|
- round
|
|
|
- class="dialog-btn"
|
|
|
- color="linear-gradient(90deg, #ff7a00, #ffa94d)"
|
|
|
- @click="handleConfirm"
|
|
|
+ <!-- 按钮区:支持 1 或 2 个按钮 -->
|
|
|
+ <div
|
|
|
+ class="dialog-actions"
|
|
|
+ :class="{
|
|
|
+ two: hasConfirm && hasCancel,
|
|
|
+ one: hasConfirm !== hasCancel,
|
|
|
+ }"
|
|
|
>
|
|
|
- {{ confirmText }}
|
|
|
- </van-button>
|
|
|
+ <!-- 失败/取消:无背景,边框+文字色由 color 控制 -->
|
|
|
+ <van-button
|
|
|
+ v-if="hasCancel"
|
|
|
+ plain
|
|
|
+ class="btn btn--fail"
|
|
|
+ :color="cancelColor"
|
|
|
+ round
|
|
|
+ @click="handleCancel"
|
|
|
+ >
|
|
|
+ {{ cancelText }}
|
|
|
+ </van-button>
|
|
|
+
|
|
|
+ <!-- 成功/确定:填充背景,支持渐变 -->
|
|
|
+ <van-button
|
|
|
+ v-if="hasConfirm"
|
|
|
+ type="primary"
|
|
|
+ class="btn btn--success"
|
|
|
+ :color="confirmColor"
|
|
|
+ round
|
|
|
+ @click="handleConfirm"
|
|
|
+ >
|
|
|
+ {{ confirmText }}
|
|
|
+ </van-button>
|
|
|
+ </div>
|
|
|
</div>
|
|
|
</div>
|
|
|
</transition>
|
|
|
</template>
|
|
|
|
|
|
<script setup lang="ts">
|
|
|
-import { defineProps, defineEmits } from 'vue'
|
|
|
+import { computed } from 'vue'
|
|
|
|
|
|
const props = defineProps({
|
|
|
show: { type: Boolean, required: true },
|
|
|
title: { type: String, default: '提示' },
|
|
|
message: { type: String, default: '' },
|
|
|
- confirmText: { type: String, default: '确定' },
|
|
|
+
|
|
|
+ /** 成功按钮(右侧) */
|
|
|
+ confirmText: { type: String, default: '' },
|
|
|
+ /** 失败按钮(左侧),无背景 */
|
|
|
+ cancelText: { type: String, default: '' },
|
|
|
+
|
|
|
+ /** 成功按钮背景色(可用渐变) */
|
|
|
+ confirmColor: {
|
|
|
+ type: String,
|
|
|
+ default: 'linear-gradient(90deg, #ff7a00, #ffa94d)',
|
|
|
+ },
|
|
|
+ /** 失败按钮文字/边框颜色(plain 模式下作为描边+文字色) */
|
|
|
+ cancelColor: {
|
|
|
+ type: String,
|
|
|
+ default: '#fe783d',
|
|
|
+ },
|
|
|
+
|
|
|
+ /** 点击遮罩是否关闭 */
|
|
|
closeOnClickOverlay: { type: Boolean, default: true },
|
|
|
})
|
|
|
|
|
|
-const emit = defineEmits(['update:show', 'confirm', 'close'])
|
|
|
+const emit = defineEmits<{
|
|
|
+ (e: 'update:show', v: boolean): void
|
|
|
+ (e: 'confirm'): void
|
|
|
+ (e: 'cancel'): void
|
|
|
+ (e: 'close'): void
|
|
|
+}>()
|
|
|
|
|
|
-const handleConfirm = () => {
|
|
|
- emit('confirm') // 让父组件自己处理逻辑
|
|
|
-}
|
|
|
+const hasConfirm = computed(() => !!props.confirmText)
|
|
|
+const hasCancel = computed(() => !!props.cancelText)
|
|
|
|
|
|
+const handleConfirm = () => emit('confirm')
|
|
|
+const handleCancel = () => emit('cancel')
|
|
|
const handleClose = () => {
|
|
|
if (props.closeOnClickOverlay) emit('update:show', false)
|
|
|
emit('close')
|
|
|
@@ -55,8 +100,7 @@ const handleClose = () => {
|
|
|
|
|
|
.modern-dialog {
|
|
|
position: fixed;
|
|
|
- top: 50%;
|
|
|
- left: 50%;
|
|
|
+ inset: 50% auto auto 50%;
|
|
|
transform: translate(-50%, -50%);
|
|
|
z-index: 9999;
|
|
|
width: 80vw;
|
|
|
@@ -88,23 +132,48 @@ const handleClose = () => {
|
|
|
word-break: break-word;
|
|
|
}
|
|
|
|
|
|
- .dialog-btn {
|
|
|
- width: calc(100% - 10vw);
|
|
|
- margin: 0 auto 2.5vw;
|
|
|
- height: 12vw;
|
|
|
- border-radius: 3vw;
|
|
|
- font-size: 4vw;
|
|
|
- font-weight: 600;
|
|
|
- display: inline-flex;
|
|
|
- align-items: center;
|
|
|
- justify-content: center;
|
|
|
- border: none;
|
|
|
- box-shadow: 0 4px 12px rgba(255, 128, 54, 0.25);
|
|
|
- letter-spacing: 0.2vw;
|
|
|
+ /* 按钮区域布局 */
|
|
|
+ .dialog-actions {
|
|
|
+ width: 100%;
|
|
|
+ padding: 0 5vw 2.5vw;
|
|
|
+ box-sizing: border-box;
|
|
|
+ display: grid;
|
|
|
+ gap: 3vw;
|
|
|
+
|
|
|
+ &.one {
|
|
|
+ grid-template-columns: 1fr;
|
|
|
+
|
|
|
+ .btn {
|
|
|
+ height: 12vw;
|
|
|
+ border-radius: 3vw;
|
|
|
+ font-size: 4vw;
|
|
|
+ font-weight: 600;
|
|
|
+ letter-spacing: 0.2vw;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ &.two {
|
|
|
+ grid-template-columns: 1fr 1fr;
|
|
|
+
|
|
|
+ .btn {
|
|
|
+ height: 12vw;
|
|
|
+ border-radius: 3vw;
|
|
|
+ font-size: 4vw;
|
|
|
+ font-weight: 600;
|
|
|
+ letter-spacing: 0.2vw;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* 失败按钮:无背景(plain),加淡边框 */
|
|
|
+ .btn--fail {
|
|
|
+ /* 让边框略淡一些,视觉层次更好 */
|
|
|
+ border-width: 1px;
|
|
|
+ background-color: #fe783d;
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-/* 动画 */
|
|
|
+/* 过渡动画 */
|
|
|
.dialog-pop-enter-active,
|
|
|
.dialog-pop-leave-active {
|
|
|
transition: all 0.25s ease;
|