11<script setup lang="ts">
2- import { computed , provide } from ' vue'
2+ import { computed , provide , ref } from ' vue'
33
44import { WindowToggleMaximise } from ' @/bridge'
55import useI18n from ' @/lang'
66
77export interface Props {
8- open: boolean
98 title? : string
109 footer? : boolean
1110 maxHeight? : string
@@ -19,6 +18,10 @@ export interface Props {
1918 cancelText? : string
2019 submitText? : string
2120 maskClosable? : boolean
21+ onOk? : () => MaybePromise <boolean | void >
22+ onCancel? : () => MaybePromise <boolean | void >
23+ beforeClose? : (isOk : boolean ) => MaybePromise <boolean | void >
24+ afterClose? : (isOk : boolean ) => void
2225}
2326
2427const props = withDefaults (defineProps <Props >(), {
@@ -37,16 +40,32 @@ const props = withDefaults(defineProps<Props>(), {
3740 maskClosable: false ,
3841})
3942
43+ const open = defineModel (' open' , { default: false })
44+
45+ const cancelLoading = ref (false )
46+ const submitLoading = ref (false )
47+
4048const { t } = useI18n .global
4149
42- const emits = defineEmits ([' update:open' , ' ok' ])
50+ const handleAction = async (isOk : boolean ) => {
51+ const loading = isOk ? submitLoading : cancelLoading
52+ const action = isOk ? props .onOk : props .onCancel
53+
54+ loading .value = true
55+ try {
56+ if (! ((await action ?.()) ?? true ) || ! ((await props .beforeClose ?.(isOk )) ?? true )) {
57+ return
58+ }
59+ } finally {
60+ loading .value = false
61+ }
4362
44- const handleSubmit = () => {
45- emits (' update:open' , false )
46- emits (' ok' )
63+ open .value = false
64+ props .afterClose ?.(isOk )
4765}
4866
49- const handleCancel = () => emits (' update:open' , false )
67+ const handleSubmit = () => handleAction (true )
68+ const handleCancel = () => handleAction (false )
5069
5170const onMaskClick = () => props .maskClosable && handleCancel ()
5271
@@ -81,10 +100,17 @@ provide('submit', handleSubmit)
81100 </div >
82101 <div v-if =" footer" class =" action" >
83102 <slot name =" action" />
84- <Button v-if =" cancel" @click =" handleCancel" :type =" maskClosable ? 'text' : 'normal'" >
103+ <Button
104+ v-if =" cancel"
105+ @click =" handleCancel"
106+ :loading =" cancelLoading"
107+ :type =" maskClosable ? 'text' : 'normal'"
108+ >
85109 {{ t(cancelText) }}
86110 </Button >
87- <Button v-if =" submit" @click =" handleSubmit" type =" primary" >{{ t(submitText) }}</Button >
111+ <Button v-if =" submit" @click =" handleSubmit" :loading =" submitLoading" type =" primary" >
112+ {{ t(submitText) }}
113+ </Button >
88114 </div >
89115 </div >
90116 </div >
0 commit comments