Pārlūkot izejas kodu

feat: modal support destroy on close

Netfan 2 mēneši atpakaļ
vecāks
revīzija
4a8e6abc06

+ 4 - 0
packages/@core/ui-kit/popup-ui/src/modal/modal.ts

@@ -143,6 +143,10 @@ export interface ModalApiOptions extends ModalState {
    * 独立的弹窗组件
    */
   connectedComponent?: Component;
+  /**
+   * 在关闭时销毁弹窗。仅在使用 connectedComponent 时有效
+   */
+  destroyOnClose?: boolean;
   /**
    * 关闭前的回调,返回 false 可以阻止关闭
    * @returns

+ 23 - 2
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';
 
@@ -18,6 +26,7 @@ export function useVbenModal<TParentModalProps extends ModalProps = ModalProps>(
   const { connectedComponent } = options;
   if (connectedComponent) {
     const extendedApi = reactive({});
+    const isModalReady = ref(true);
     const Modal = defineComponent(
       (props: TParentModalProps, { attrs, slots }) => {
         provide(USER_MODAL_INJECT_KEY, {
@@ -27,6 +36,11 @@ export function useVbenModal<TParentModalProps extends ModalProps = ModalProps>(
             Object.setPrototypeOf(extendedApi, api);
           },
           options,
+          async reCreateModal() {
+            isModalReady.value = false;
+            await nextTick();
+            isModalReady.value = true;
+          },
         });
         checkProps(extendedApi as ExtendedModalApi, {
           ...props,
@@ -35,7 +49,7 @@ export function useVbenModal<TParentModalProps extends ModalProps = ModalProps>(
         });
         return () =>
           h(
-            connectedComponent,
+            isModalReady.value ? connectedComponent : 'div',
             {
               ...props,
               ...attrs,
@@ -62,6 +76,13 @@ export function useVbenModal<TParentModalProps extends ModalProps = ModalProps>(
     options.onOpenChange?.(isOpen);
     injectData.options?.onOpenChange?.(isOpen);
   };
+
+  mergedOptions.onClosed = () => {
+    options.onClosed?.();
+    if (options.destroyOnClose) {
+      injectData.reCreateModal?.();
+    }
+  };
   const api = new ModalApi(mergedOptions);
 
   const extendedApi: ExtendedModalApi = api as never;