Skip to content

Commit 6febfea

Browse files
committed
feat: FaModal 组件增加 beforeClose 回调函数,优化关闭逻辑并支持异步处理
1 parent 3859c26 commit 6febfea

File tree

2 files changed

+61
-21
lines changed

2 files changed

+61
-21
lines changed

‎src/ui/components/FaModal/index.ts‎

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@ export interface ModalProps {
2222
cancelButtonText?: string
2323
confirmButtonDisabled?: boolean
2424
confirmButtonLoading?: boolean
25+
beforeClose?: (
26+
action: 'confirm' | 'cancel' | 'close',
27+
done: () => void
28+
) => void
2529
header?: boolean
2630
footer?: boolean
2731
closeOnClickOverlay?: boolean
@@ -30,7 +34,6 @@ export interface ModalProps {
3034
headerClass?: HTMLAttributes['class']
3135
contentClass?: HTMLAttributes['class']
3236
footerClass?: HTMLAttributes['class']
33-
modalId?: string
3437
}
3538
export interface ModalEmits {
3639
'update:modelValue': [value: boolean]
@@ -44,13 +47,13 @@ export interface ModalEmits {
4447

4548
type alertOptions = Pick<ModalProps, 'title' | 'description' | 'icon' | 'alignCenter' | 'overlay' | 'overlayBlur' | 'confirmButtonText' | 'confirmButtonDisabled' | 'confirmButtonLoading' | 'closeOnClickOverlay' | 'closeOnPressEscape' | 'class' | 'headerClass' | 'contentClass' | 'footerClass'> & {
4649
content: string
47-
onConfirm?: () => any
50+
onConfirm?: () => void
4851
}
4952

50-
type confirmOptions = Pick<ModalProps, 'title' | 'description' | 'alignCenter' | 'overlay' | 'overlayBlur' | 'confirmButtonText' | 'cancelButtonText' | 'confirmButtonDisabled' | 'confirmButtonLoading' | 'closeOnClickOverlay' | 'closeOnPressEscape' | 'class' | 'headerClass' | 'contentClass' | 'footerClass'> & {
53+
type confirmOptions = Pick<ModalProps, 'title' | 'description' | 'alignCenter' | 'overlay' | 'overlayBlur' | 'confirmButtonText' | 'cancelButtonText' | 'confirmButtonDisabled' | 'confirmButtonLoading' | 'beforeClose' | 'closeOnClickOverlay' | 'closeOnPressEscape' | 'class' | 'headerClass' | 'contentClass' | 'footerClass'> & {
5154
content: string
52-
onConfirm?: () => any
53-
onCancel?: () => any
55+
onConfirm?: () => void
56+
onCancel?: () => void
5457
}
5558

5659
export function useFaModal() {
@@ -67,7 +70,6 @@ export function useFaModal() {
6770
closeOnClickOverlay: false,
6871
contentClass: 'py-0 min-h-auto',
6972
footerClass: 'p-4',
70-
modalId: useId(),
7173
onClosed: () => {
7274
app.unmount()
7375
},
@@ -89,7 +91,6 @@ export function useFaModal() {
8991
closeOnClickOverlay: false,
9092
contentClass: 'py-0 min-h-auto',
9193
footerClass: 'p-4',
92-
modalId: useId(),
9394
onClosed: () => {
9495
app.unmount()
9596
},
@@ -111,7 +112,6 @@ export function useFaModal() {
111112
closeOnClickOverlay: false,
112113
contentClass: 'py-0 min-h-auto',
113114
footerClass: 'p-4',
114-
modalId: useId(),
115115
onClosed: () => {
116116
app.unmount()
117117
},
@@ -133,7 +133,6 @@ export function useFaModal() {
133133
closeOnClickOverlay: false,
134134
contentClass: 'py-0 min-h-auto',
135135
footerClass: 'p-4',
136-
modalId: useId(),
137136
onClosed: () => {
138137
app.unmount()
139138
},
@@ -155,7 +154,6 @@ export function useFaModal() {
155154
contentClass: 'py-0 min-h-auto',
156155
footerClass: 'p-4',
157156
showCancelButton: true,
158-
modalId: useId(),
159157
onClosed: () => {
160158
app.unmount()
161159
},

‎src/ui/components/FaModal/index.vue‎

Lines changed: 53 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -83,35 +83,77 @@ function setTransform() {
8383
}
8484
8585
watch(isOpen, (val) => {
86+
emits('update:modelValue', val)
8687
if (val) {
8788
nextTick(() => {
8889
if (dialogContentRef.value) {
8990
dialogRef.value = dialogContentRef.value.el?.$el
9091
setTransform()
9192
}
9293
})
94+
emits('open')
95+
}
96+
else {
97+
emits('close')
9398
}
9499
})
95100
96-
function updateOpen(value: boolean) {
97-
isOpen.value = value
98-
emits('update:modelValue', value)
101+
async function updateOpen(value: boolean) {
99102
if (value) {
103+
isOpen.value = value
100104
emits('open')
101105
}
102106
else {
103-
emits('close')
107+
if (props.beforeClose) {
108+
await props.beforeClose(
109+
'close',
110+
() => {
111+
isOpen.value = value
112+
emits('close')
113+
},
114+
)
115+
}
116+
else {
117+
isOpen.value = value
118+
emits('close')
119+
}
104120
}
105121
}
106122
107-
function onConfirm() {
108-
updateOpen(false)
109-
emits('confirm')
123+
const isConfirmButtonLoading = ref(false)
124+
125+
async function onConfirm() {
126+
if (props.beforeClose) {
127+
isConfirmButtonLoading.value = true
128+
await props.beforeClose(
129+
'confirm',
130+
() => {
131+
isOpen.value = false
132+
emits('confirm')
133+
},
134+
)
135+
isConfirmButtonLoading.value = false
136+
}
137+
else {
138+
isOpen.value = false
139+
emits('confirm')
140+
}
110141
}
111142
112-
function onCancel() {
113-
updateOpen(false)
114-
emits('cancel')
143+
async function onCancel() {
144+
if (props.beforeClose) {
145+
await props.beforeClose(
146+
'cancel',
147+
() => {
148+
isOpen.value = false
149+
emits('cancel')
150+
},
151+
)
152+
}
153+
else {
154+
isOpen.value = false
155+
emits('cancel')
156+
}
115157
}
116158
117159
function handleFocusOutside(e: Event) {
@@ -223,7 +265,7 @@ function handleAnimationEnd() {
223265
<FaButton v-if="showCancelButton" variant="outline" @click="onCancel">
224266
{{ cancelButtonText }}
225267
</FaButton>
226-
<FaButton v-if="showConfirmButton" :disabled="confirmButtonDisabled" :loading="confirmButtonLoading" @click="onConfirm">
268+
<FaButton v-if="showConfirmButton" :disabled="confirmButtonDisabled" :loading="confirmButtonLoading || isConfirmButtonLoading" @click="onConfirm">
227269
{{ confirmButtonText }}
228270
</FaButton>
229271
</slot>

0 commit comments

Comments
 (0)