feat(弹窗组件): 新增纯信息弹窗showMessage
This commit is contained in:
parent
7b9472258b
commit
9cf9464d9c
@ -1,19 +1,19 @@
|
||||
<template>
|
||||
<div v-if="visible" class="modal-overlay" @click="handleOverlayClick">
|
||||
<div class="modal" :class="[animationClass, modalTypeClass]">
|
||||
<!-- 图标 -->
|
||||
<div class="modal-icon">
|
||||
<!-- 图标 - simple 类型不显示 -->
|
||||
<div class="modal-icon" v-if="!isSimple">
|
||||
<div class="icon-circle" :class="iconCircleClass">
|
||||
<span class="icon-symbol" :class="iconSymbolClass">{{ iconSymbol }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 标题 -->
|
||||
<div class="modal-title" v-if="title">{{ title }}</div>
|
||||
|
||||
|
||||
<!-- 标题 - simple 类型不显示 -->
|
||||
<div class="modal-title" v-if="title && !isSimple">{{ title }}</div>
|
||||
|
||||
<!-- 消息内容 -->
|
||||
<div class="modal-message">{{ message }}</div>
|
||||
|
||||
|
||||
<!-- 按钮 -->
|
||||
<div class="modal-actions">
|
||||
<button class="modal-btn" :class="buttonClass" @click="confirm">{{ confirmText }}</button>
|
||||
@ -28,29 +28,29 @@ import { ref, onMounted, computed } from 'vue'
|
||||
const props = defineProps({
|
||||
title: {
|
||||
type: String,
|
||||
default: 'Notice'
|
||||
default: 'Notice',
|
||||
},
|
||||
message: {
|
||||
type: String,
|
||||
required: true
|
||||
required: true,
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
default: 'error', // 'error' | 'warning' | 'success' | 'info'
|
||||
validator: (value) => ['error', 'warning', 'success', 'info'].includes(value)
|
||||
validator: (value) => ['error', 'warning', 'success', 'info', 'simple'].includes(value), // 新增 simple
|
||||
},
|
||||
confirmText: {
|
||||
type: String,
|
||||
default: 'OK'
|
||||
default: 'OK',
|
||||
},
|
||||
clickToClose: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
default: true,
|
||||
},
|
||||
duration: {
|
||||
type: Number,
|
||||
default: null // 自动关闭时间(毫秒)
|
||||
}
|
||||
default: null, // 自动关闭时间(毫秒)
|
||||
},
|
||||
})
|
||||
|
||||
const emit = defineEmits(['confirm', 'close'])
|
||||
@ -58,13 +58,16 @@ const emit = defineEmits(['confirm', 'close'])
|
||||
const visible = ref(false)
|
||||
const animationClass = ref('')
|
||||
|
||||
// 新增计算属性,判断是否显示图标和标题
|
||||
const isSimple = computed(() => props.type === 'simple')
|
||||
|
||||
// 根据类型计算图标和样式
|
||||
const iconSymbol = computed(() => {
|
||||
const symbols = {
|
||||
error: '✕',
|
||||
warning: '⚠',
|
||||
success: '✓',
|
||||
info: 'i'
|
||||
info: 'i',
|
||||
}
|
||||
return symbols[props.type] || symbols.error
|
||||
})
|
||||
@ -80,7 +83,7 @@ const buttonClass = computed(() => `modal-btn-${props.type}`)
|
||||
const show = () => {
|
||||
visible.value = true
|
||||
animationClass.value = 'modal-enter'
|
||||
|
||||
|
||||
// 如果设置了自动关闭时间
|
||||
if (props.duration && props.duration > 0) {
|
||||
setTimeout(() => {
|
||||
@ -116,7 +119,7 @@ onMounted(() => {
|
||||
// 暴露方法给父组件
|
||||
defineExpose({
|
||||
show,
|
||||
close
|
||||
close,
|
||||
})
|
||||
</script>
|
||||
|
||||
@ -139,7 +142,9 @@ defineExpose({
|
||||
.modal {
|
||||
background: white;
|
||||
border-radius: 16px;
|
||||
box-shadow: 0 20px 25px rgba(0, 0, 0, 0.1), 0 10px 10px rgba(0, 0, 0, 0.04);
|
||||
box-shadow:
|
||||
0 20px 25px rgba(0, 0, 0, 0.1),
|
||||
0 10px 10px rgba(0, 0, 0, 0.04);
|
||||
width: 100%;
|
||||
max-width: 320px;
|
||||
padding: 24px 20px 20px;
|
||||
@ -175,7 +180,7 @@ defineExpose({
|
||||
.modal-title {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: #1F2937;
|
||||
color: #1f2937;
|
||||
margin-bottom: 12px;
|
||||
line-height: 1.4;
|
||||
}
|
||||
@ -183,7 +188,7 @@ defineExpose({
|
||||
/* 消息内容 */
|
||||
.modal-message {
|
||||
font-size: 14px;
|
||||
color: #6B7280;
|
||||
color: #6b7280;
|
||||
line-height: 1.5;
|
||||
margin-bottom: 20px;
|
||||
word-wrap: break-word;
|
||||
@ -213,52 +218,52 @@ defineExpose({
|
||||
|
||||
/* Error 类型样式 */
|
||||
.modal-error .icon-circle-error {
|
||||
background-color: #FEE2E2;
|
||||
border-color: #FECACA;
|
||||
background-color: #fee2e2;
|
||||
border-color: #fecaca;
|
||||
}
|
||||
|
||||
.modal-error .icon-symbol-error {
|
||||
color: #DC2626;
|
||||
color: #dc2626;
|
||||
}
|
||||
|
||||
.modal-error .modal-btn-error {
|
||||
background-color: #DC2626;
|
||||
background-color: #dc2626;
|
||||
}
|
||||
|
||||
.modal-error .modal-btn-error:hover {
|
||||
background-color: #B91C1C;
|
||||
background-color: #b91c1c;
|
||||
}
|
||||
|
||||
.modal-error .modal-btn-error:active {
|
||||
background-color: #991B1B;
|
||||
background-color: #991b1b;
|
||||
}
|
||||
|
||||
/* Warning 类型样式 */
|
||||
.modal-warning .icon-circle-warning {
|
||||
background-color: #FEF3C7;
|
||||
border-color: #FDE68A;
|
||||
background-color: #fef3c7;
|
||||
border-color: #fde68a;
|
||||
}
|
||||
|
||||
.modal-warning .icon-symbol-warning {
|
||||
color: #D97706;
|
||||
color: #d97706;
|
||||
}
|
||||
|
||||
.modal-warning .modal-btn-warning {
|
||||
background-color: #D97706;
|
||||
background-color: #d97706;
|
||||
}
|
||||
|
||||
.modal-warning .modal-btn-warning:hover {
|
||||
background-color: #B45309;
|
||||
background-color: #b45309;
|
||||
}
|
||||
|
||||
.modal-warning .modal-btn-warning:active {
|
||||
background-color: #92400E;
|
||||
background-color: #92400e;
|
||||
}
|
||||
|
||||
/* Success 类型样式 */
|
||||
.modal-success .icon-circle-success {
|
||||
background-color: #D1FAE5;
|
||||
border-color: #A7F3D0;
|
||||
background-color: #d1fae5;
|
||||
border-color: #a7f3d0;
|
||||
}
|
||||
|
||||
.modal-success .icon-symbol-success {
|
||||
@ -274,29 +279,48 @@ defineExpose({
|
||||
}
|
||||
|
||||
.modal-success .modal-btn-success:active {
|
||||
background-color: #065F46;
|
||||
background-color: #065f46;
|
||||
}
|
||||
|
||||
/* Info 类型样式 */
|
||||
.modal-info .icon-circle-info {
|
||||
background-color: #DBEAFE;
|
||||
border-color: #BFDBFE;
|
||||
background-color: #dbeafe;
|
||||
border-color: #bfdbfe;
|
||||
}
|
||||
|
||||
.modal-info .icon-symbol-info {
|
||||
color: #2563EB;
|
||||
color: #2563eb;
|
||||
}
|
||||
|
||||
.modal-info .modal-btn-info {
|
||||
background-color: #2563EB;
|
||||
background-color: #2563eb;
|
||||
}
|
||||
|
||||
.modal-info .modal-btn-info:hover {
|
||||
background-color: #1D4ED8;
|
||||
background-color: #1d4ed8;
|
||||
}
|
||||
|
||||
.modal-info .modal-btn-info:active {
|
||||
background-color: #1E40AF;
|
||||
background-color: #1e40af;
|
||||
}
|
||||
|
||||
/* 新增 simple 类型样式 */
|
||||
.modal-simple .modal-message {
|
||||
font-size: 15px;
|
||||
color: #374151;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.modal-simple .modal-btn {
|
||||
background-color: #2563eb;
|
||||
}
|
||||
|
||||
.modal-simple .modal-btn:hover {
|
||||
background-color: #1d4ed8;
|
||||
}
|
||||
|
||||
.modal-simple .modal-btn:active {
|
||||
background-color: #1e40af;
|
||||
}
|
||||
|
||||
/* 动画效果 */
|
||||
@ -350,20 +374,20 @@ defineExpose({
|
||||
max-width: 280px;
|
||||
padding: 20px 16px 16px;
|
||||
}
|
||||
|
||||
|
||||
.icon-circle {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
}
|
||||
|
||||
|
||||
.icon-symbol {
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
|
||||
.modal-title {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
|
||||
.modal-message {
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
@ -109,6 +109,15 @@ export const showToast = (message, options = {}) => {
|
||||
return errorModal.show(message, defaultOptions)
|
||||
}
|
||||
|
||||
export const showMessage = (message, options = {}) => {
|
||||
const defaultOptions = {
|
||||
confirmText: i18n.global.t('ok') || 'OK',
|
||||
type: 'simple',
|
||||
...options,
|
||||
}
|
||||
return errorModal.show(message, defaultOptions)
|
||||
}
|
||||
|
||||
// 错误处理的专用方法
|
||||
export const handleError = (error) => {
|
||||
let message = i18n.global.t('unknown_error') || 'An unknown error occurred'
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user