From afce9dc5c06531e83d076eefeffc57debac126b7 Mon Sep 17 00:00:00 2001 From: ming4762 Date: Sun, 13 Apr 2025 23:02:07 +0800 Subject: [PATCH] perf: improve `destroyOnClose` for `VbenModal` (#5935) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * perf: 优化Vben Modal destroyOnClose,解决destroyOnClose=false,Modal依旧会被销毁的问题 影响范围(重要):destroyOnClose默认为true,这会导致所有的modal都会默认渲染到body radix-vue Dialog组件默认会销毁挂载的组件,所以即使destroyOnClose=false,Modal依旧会被销毁的问题 对于一些大表单重复渲染导致卡顿,ApiComponent也会频繁的加载数据 * fix: modal closing animation --------- Co-authored-by: Netfan --- docs/src/components/common-ui/vben-modal.md | 3 +-- .../ui-kit/popup-ui/src/modal/modal-api.ts | 1 + .../@core/ui-kit/popup-ui/src/modal/modal.ts | 8 +++--- .../@core/ui-kit/popup-ui/src/modal/modal.vue | 23 ++++++++++++++-- .../ui-kit/popup-ui/src/modal/use-modal.ts | 26 ++----------------- .../views/examples/modal/auto-height-demo.vue | 11 +++++--- .../views/examples/modal/in-content-demo.vue | 4 +-- playground/src/views/examples/modal/index.vue | 2 +- 8 files changed, 39 insertions(+), 39 deletions(-) diff --git a/docs/src/components/common-ui/vben-modal.md b/docs/src/components/common-ui/vben-modal.md index 39b88cf9..72fdf9cf 100644 --- a/docs/src/components/common-ui/vben-modal.md +++ b/docs/src/components/common-ui/vben-modal.md @@ -60,7 +60,6 @@ Modal 内的内容一般业务中,会比较复杂,所以我们可以将 moda - `VbenModal` 组件对与参数的处理优先级是 `slot` > `props` > `state`(通过api更新的状态以及useVbenModal参数)。如果你已经传入了 `slot` 或者 `props`,那么 `setState` 将不会生效,这种情况下你可以通过 `slot` 或者 `props` 来更新状态。 - 如果你使用到了 `connectedComponent` 参数,那么会存在 2 个`useVbenModal`, 此时,如果同时设置了相同的参数,那么以内部为准(也就是没有设置 connectedComponent 的代码)。比如 同时设置了 `onConfirm`,那么以内部的 `onConfirm` 为准。`onOpenChange`事件除外,内外都会触发。 -- 使用了`connectedComponent`参数时,可以配置`destroyOnClose`属性来决定当关闭弹窗时,是否要销毁`connectedComponent`组件(重新创建`connectedComponent`组件,这将会把其内部所有的变量、状态、数据等恢复到初始状态。)。 - 如果弹窗的默认行为不符合你的预期,可以在`src\bootstrap.ts`中修改`setDefaultModalProps`的参数来设置默认的属性,如默认隐藏全屏按钮,修改默认ZIndex等。 ::: @@ -84,7 +83,7 @@ const [Modal, modalApi] = useVbenModal({ | --- | --- | --- | --- | | appendToMain | 是否挂载到内容区域(默认挂载到body) | `boolean` | `false` | | connectedComponent | 连接另一个Modal组件 | `Component` | - | -| destroyOnClose | 关闭时销毁`connectedComponent` | `boolean` | `false` | +| destroyOnClose | 关闭时销毁 | `boolean` | `false` | | title | 标题 | `string\|slot` | - | | titleTooltip | 标题提示信息 | `string\|slot` | - | | description | 描述信息 | `string\|slot` | - | diff --git a/packages/@core/ui-kit/popup-ui/src/modal/modal-api.ts b/packages/@core/ui-kit/popup-ui/src/modal/modal-api.ts index 97790969..27aa8216 100644 --- a/packages/@core/ui-kit/popup-ui/src/modal/modal-api.ts +++ b/packages/@core/ui-kit/popup-ui/src/modal/modal-api.ts @@ -44,6 +44,7 @@ export class ModalApi { confirmDisabled: false, confirmLoading: false, contentClass: '', + destroyOnClose: true, draggable: false, footer: true, footerClass: '', diff --git a/packages/@core/ui-kit/popup-ui/src/modal/modal.ts b/packages/@core/ui-kit/popup-ui/src/modal/modal.ts index 9f86ab8c..2dbab9e4 100644 --- a/packages/@core/ui-kit/popup-ui/src/modal/modal.ts +++ b/packages/@core/ui-kit/popup-ui/src/modal/modal.ts @@ -60,6 +60,10 @@ export interface ModalProps { * 弹窗描述 */ description?: string; + /** + * 在关闭时销毁弹窗 + */ + destroyOnClose?: boolean; /** * 是否可拖拽 * @default false @@ -153,10 +157,6 @@ export interface ModalApiOptions extends ModalState { * 独立的弹窗组件 */ connectedComponent?: Component; - /** - * 在关闭时销毁弹窗。仅在使用 connectedComponent 时有效 - */ - destroyOnClose?: boolean; /** * 关闭前的回调,返回 false 可以阻止关闭 * @returns diff --git a/packages/@core/ui-kit/popup-ui/src/modal/modal.vue b/packages/@core/ui-kit/popup-ui/src/modal/modal.vue index 6fe3d621..000cba9f 100644 --- a/packages/@core/ui-kit/popup-ui/src/modal/modal.vue +++ b/packages/@core/ui-kit/popup-ui/src/modal/modal.vue @@ -1,7 +1,7 @@ diff --git a/playground/src/views/examples/modal/in-content-demo.vue b/playground/src/views/examples/modal/in-content-demo.vue index b51d363f..7ffe7b77 100644 --- a/playground/src/views/examples/modal/in-content-demo.vue +++ b/playground/src/views/examples/modal/in-content-demo.vue @@ -24,7 +24,7 @@ const value = ref(); title="基础弹窗示例" title-tooltip="标题提示内容" > - 此弹窗指定在内容区域打开 - + 此弹窗指定在内容区域打开,并且在关闭之后弹窗内容不会被销毁 + diff --git a/playground/src/views/examples/modal/index.vue b/playground/src/views/examples/modal/index.vue index 7401737a..3ed6cdea 100644 --- a/playground/src/views/examples/modal/index.vue +++ b/playground/src/views/examples/modal/index.vue @@ -198,7 +198,7 @@ async function openPrompt() { - +

在内容区域打开弹窗的示例