优化构架
This commit is contained in:
@@ -0,0 +1,95 @@
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue'
|
||||
|
||||
export type DialogConfirmType = 'primary' | 'success' | 'warning' | 'danger' | 'info'
|
||||
|
||||
defineOptions({ inheritAttrs: false })
|
||||
|
||||
const props = withDefaults(defineProps<{
|
||||
title: string
|
||||
width?: string | number
|
||||
loading?: boolean
|
||||
confirmLoading?: boolean
|
||||
confirmDisabled?: boolean
|
||||
confirmText?: string
|
||||
cancelText?: string
|
||||
confirmType?: DialogConfirmType
|
||||
showFooter?: boolean
|
||||
showCancel?: boolean
|
||||
showConfirm?: boolean
|
||||
showClose?: boolean
|
||||
closeOnClickModal?: boolean
|
||||
closeOnPressEscape?: boolean
|
||||
destroyOnClose?: boolean
|
||||
lockWhileSubmitting?: boolean
|
||||
}>(), {
|
||||
width: 'min(560px, calc(100vw - 28px))',
|
||||
loading: false,
|
||||
confirmLoading: false,
|
||||
confirmDisabled: false,
|
||||
confirmText: '确定',
|
||||
cancelText: '取消',
|
||||
confirmType: 'primary',
|
||||
showFooter: true,
|
||||
showCancel: true,
|
||||
showConfirm: true,
|
||||
showClose: true,
|
||||
closeOnClickModal: false,
|
||||
closeOnPressEscape: true,
|
||||
destroyOnClose: false,
|
||||
lockWhileSubmitting: true,
|
||||
})
|
||||
|
||||
const open = defineModel<boolean>({ default: false })
|
||||
const emit = defineEmits<{
|
||||
confirm: []
|
||||
cancel: []
|
||||
}>()
|
||||
const submittingLocked = computed(() => props.lockWhileSubmitting && props.confirmLoading)
|
||||
|
||||
function closeDialog() {
|
||||
if (submittingLocked.value) return
|
||||
open.value = false
|
||||
emit('cancel')
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<el-dialog
|
||||
v-bind="$attrs"
|
||||
v-model="open"
|
||||
class="app-dialog"
|
||||
:title="title"
|
||||
:width="width"
|
||||
:show-close="showClose && !submittingLocked"
|
||||
:close-on-click-modal="closeOnClickModal && !submittingLocked"
|
||||
:close-on-press-escape="closeOnPressEscape && !submittingLocked"
|
||||
:destroy-on-close="destroyOnClose"
|
||||
>
|
||||
<template v-if="$slots.header" #header><slot name="header" /></template>
|
||||
<div v-loading="loading" class="app-dialog__body" :aria-busy="loading || confirmLoading">
|
||||
<slot />
|
||||
</div>
|
||||
<template v-if="showFooter" #footer>
|
||||
<slot name="footer" :close="closeDialog" :submitting="confirmLoading">
|
||||
<div class="app-dialog__footer">
|
||||
<el-button v-if="showCancel" :disabled="submittingLocked" @click="closeDialog">{{ cancelText }}</el-button>
|
||||
<el-button
|
||||
v-if="showConfirm"
|
||||
:type="confirmType"
|
||||
:loading="confirmLoading"
|
||||
:disabled="loading || confirmDisabled"
|
||||
@click="emit('confirm')"
|
||||
>{{ confirmText }}</el-button>
|
||||
</div>
|
||||
</slot>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.app-dialog__body { min-height: 0; }
|
||||
.app-dialog__footer { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 10px; }
|
||||
.app-dialog__footer :deep(.el-button) { margin-left: 0; }
|
||||
@media (max-width: 720px) { .app-dialog__footer :deep(.el-button) { min-height: 44px; } }
|
||||
</style>
|
||||
Reference in New Issue
Block a user