feat: FaDrawer 和 FaModal 组件新增 destroyOnClose 属性

This commit is contained in:
Hooray
2025-06-13 16:07:19 +08:00
parent 28cc84ff0e
commit 6fc89426c9
4 changed files with 41 additions and 2 deletions
+1 -1
View File
@@ -58,7 +58,7 @@ function handleCopy() {
</script>
<template>
<FaDrawer v-model="isShow" title="应用配置" description="在生产环境中应关闭该模块" :footer="isSupported" content-class="sm:min-w-md">
<FaDrawer v-model="isShow" title="应用配置" description="在生产环境中应关闭该模块" :footer="isSupported" :destroy-on-close="false" content-class="sm:min-w-md">
<div class="rounded-2 bg-rose/20 px-4 py-2 text-sm/6 c-rose">
应用配置可实时预览效果,但只是临时生效,要想真正应用于项目,可以点击下方的「复制配置」按钮,并将配置粘贴到 src/settings.ts 文件中。
</div>
+21 -1
View File
@@ -36,6 +36,7 @@ const props = withDefaults(
footer?: boolean
closeOnClickOverlay?: boolean
closeOnPressEscape?: boolean
destroyOnClose?: boolean
contentClass?: HTMLAttributes['class']
headerClass?: HTMLAttributes['class']
footerClass?: HTMLAttributes['class']
@@ -59,6 +60,7 @@ const props = withDefaults(
footer: true,
closeOnClickOverlay: true,
closeOnPressEscape: true,
destroyOnClose: true,
},
)
@@ -81,6 +83,20 @@ watch(() => props.modelValue, (newValue) => {
isOpen.value = newValue
})
const hasOpened = ref(false)
const isClosed = ref(true)
watch(() => isOpen.value, (value) => {
isClosed.value = false
if (value && !hasOpened.value) {
hasOpened.value = true
}
}, {
immediate: true,
})
const forceMount = computed(() => !props.destroyOnClose && hasOpened.value)
function updateOpen(value: boolean) {
isOpen.value = value
emits('update:modelValue', value)
@@ -127,6 +143,7 @@ function handleAnimationEnd() {
}
else {
emits('closed')
isClosed.value = true
}
}
</script>
@@ -138,8 +155,11 @@ function handleAnimationEnd() {
:open="isOpen"
:overlay="props.overlay"
:overlay-blur="props.overlayBlur"
:class="cn('w-full flex flex-col gap-0 p-0', props.contentClass)"
:class="cn('w-full flex flex-col gap-0 p-0', props.contentClass, {
hidden: isClosed,
})"
:side="props.side"
:force-mount="forceMount"
@open-auto-focus="handleFocusOutside"
@close-auto-focus="handleFocusOutside"
@focus-outside="handleFocusOutside"
+1
View File
@@ -30,6 +30,7 @@ export interface ModalProps {
footer?: boolean
closeOnClickOverlay?: boolean
closeOnPressEscape?: boolean
destroyOnClose?: boolean
class?: HTMLAttributes['class']
headerClass?: HTMLAttributes['class']
contentClass?: HTMLAttributes['class']
+18
View File
@@ -40,6 +40,7 @@ const props = withDefaults(
footer: true,
closeOnClickOverlay: true,
closeOnPressEscape: true,
destroyOnClose: true,
},
)
@@ -68,6 +69,20 @@ watch(() => props.modelValue, (newValue) => {
isOpen.value = newValue
})
const hasOpened = ref(false)
const isClosed = ref(true)
watch(() => isOpen.value, (value) => {
isClosed.value = false
if (value && !hasOpened.value) {
hasOpened.value = true
}
}, {
immediate: true,
})
const forceMount = computed(() => !props.destroyOnClose && hasOpened.value)
const { isDragging, transform } = useDraggable(
dialogRef,
dialogHeaderRef,
@@ -186,6 +201,7 @@ function handleAnimationEnd() {
}
else {
emits('closed')
isClosed.value = true
}
}
</script>
@@ -201,10 +217,12 @@ function handleAnimationEnd() {
:overlay-blur="props.overlayBlur"
:maximize="isMaximize"
:maximizable="props.maximizable"
:force-mount="forceMount"
:class="cn('left-0 right-0 top-0 md:top-[5vh] flex flex-col p-0 gap-0 mx-auto h-[calc-size(auto,size)] min-h-full md:min-h-auto max-h-full md:max-h-[90vh] translate-x-0 translate-y-0', props.class, {
'md:top-0 size-full max-w-full max-h-full md:max-h-full': isMaximize,
'md:top-1/2 md:-translate-y-1/2!': props.alignCenter,
'duration-0': isDragging,
'hidden': isClosed,
})"
@open-auto-focus="handleFocusOutside"
@close-auto-focus="handleFocusOutside"