From 14bd6dd25d1f87994d4a7084efc91d14e21a8cf9 Mon Sep 17 00:00:00 2001 From: Netfan Date: Thu, 17 Apr 2025 20:25:49 +0800 Subject: [PATCH] fix: destroyOnClose works within connectedComponent (#5989) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 修复destroyOnClose没能销毁connectedComponent自身的问题 --- docs/src/components/common-ui/vben-modal.md | 2 +- .../ui-kit/popup-ui/src/modal/use-modal.ts | 25 +++++++++++++++++-- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/docs/src/components/common-ui/vben-modal.md b/docs/src/components/common-ui/vben-modal.md index 56ff6d3c..3c8200f9 100644 --- a/docs/src/components/common-ui/vben-modal.md +++ b/docs/src/components/common-ui/vben-modal.md @@ -59,7 +59,7 @@ Modal 内的内容一般业务中,会比较复杂,所以我们可以将 moda ::: info 注意 - `VbenModal` 组件对与参数的处理优先级是 `slot` > `props` > `state`(通过api更新的状态以及useVbenModal参数)。如果你已经传入了 `slot` 或者 `props`,那么 `setState` 将不会生效,这种情况下你可以通过 `slot` 或者 `props` 来更新状态。 -- 如果你使用到了 `connectedComponent` 参数,那么会存在 2 个`useVbenModal`, 此时,如果同时设置了相同的参数,那么以内部为准(也就是没有设置 connectedComponent 的代码)。比如 同时设置了 `onConfirm`,那么以内部的 `onConfirm` 为准。`onOpenChange`事件除外,内外都会触发。 +- 如果你使用到了 `connectedComponent` 参数,那么会存在 2 个`useVbenModal`, 此时,如果同时设置了相同的参数,那么以内部为准(也就是没有设置 connectedComponent 的代码)。比如 同时设置了 `onConfirm`,那么以内部的 `onConfirm` 为准。`onOpenChange`事件除外,内外都会触发。另外,如果设置了`destroyOnClose`,内部Modal及其子组件会在被关闭后完全销毁。 - 如果弹窗的默认行为不符合你的预期,可以在`src\bootstrap.ts`中修改`setDefaultModalProps`的参数来设置默认的属性,如默认隐藏全屏按钮,修改默认ZIndex等。 ::: diff --git a/packages/@core/ui-kit/popup-ui/src/modal/use-modal.ts b/packages/@core/ui-kit/popup-ui/src/modal/use-modal.ts index 2f40ddea..61965a02 100644 --- a/packages/@core/ui-kit/popup-ui/src/modal/use-modal.ts +++ b/packages/@core/ui-kit/popup-ui/src/modal/use-modal.ts @@ -1,6 +1,14 @@ import type { ExtendedModalApi, ModalApiOptions, ModalProps } from './modal'; -import { defineComponent, h, inject, nextTick, provide, reactive } from 'vue'; +import { + defineComponent, + h, + inject, + nextTick, + provide, + reactive, + ref, +} from 'vue'; import { useStore } from '@vben-core/shared/store'; @@ -24,6 +32,7 @@ export function useVbenModal( const { connectedComponent } = options; if (connectedComponent) { const extendedApi = reactive({}); + const isModalReady = ref(true); const Modal = defineComponent( (props: TParentModalProps, { attrs, slots }) => { provide(USER_MODAL_INJECT_KEY, { @@ -33,6 +42,11 @@ export function useVbenModal( Object.setPrototypeOf(extendedApi, api); }, options, + async reCreateModal() { + isModalReady.value = false; + await nextTick(); + isModalReady.value = true; + }, }); checkProps(extendedApi as ExtendedModalApi, { ...props, @@ -41,7 +55,7 @@ export function useVbenModal( }); return () => h( - connectedComponent, + isModalReady.value ? connectedComponent : 'div', { ...props, ...attrs, @@ -70,6 +84,13 @@ export function useVbenModal( injectData.options?.onOpenChange?.(isOpen); }; + mergedOptions.onClosed = () => { + options.onClosed?.(); + if (options.destroyOnClose) { + injectData.reCreateModal?.(); + } + }; + const api = new ModalApi(mergedOptions); const extendedApi: ExtendedModalApi = api as never;