Browse Source

fix(Loading): 处理v-loading指令和useLoading的内存泄露 (#3861)

Co-authored-by: jinchuanwang <1085296443@qq.com>
wangjinchuan108 1 year ago
parent
commit
bcd98ee067

+ 9 - 2
src/components/Loading/src/createLoading.ts

@@ -19,13 +19,14 @@ export function createLoading(props?: Partial<LoadingProps>, target?: HTMLElemen
 
   vm = createVNode(LoadingWrap);
 
+  let container: Nullable<HTMLElement> = null;
   if (wait) {
     // TODO fix https://github.com/anncwb/vue-vben-admin/issues/438
     setTimeout(() => {
-      render(vm, document.createElement('div'));
+      container && render(vm, (container = document.createElement('div')));
     }, 0);
   } else {
-    render(vm, document.createElement('div'));
+    render(vm, (container = document.createElement('div')));
   }
 
   function close() {
@@ -41,6 +42,11 @@ export function createLoading(props?: Partial<LoadingProps>, target?: HTMLElemen
     target.appendChild(vm.el as HTMLElement);
   }
 
+  function destory() {
+    container && render(null, container);
+    container = vm = null;
+  }
+
   if (target) {
     open(target);
   }
@@ -48,6 +54,7 @@ export function createLoading(props?: Partial<LoadingProps>, target?: HTMLElemen
     vm,
     close,
     open,
+    destory,
     setTip: (tip: string) => {
       data.tip = tip;
     },

+ 6 - 1
src/components/Loading/src/useLoading.ts

@@ -1,7 +1,8 @@
 import { unref } from 'vue';
+import type { Ref } from 'vue';
+import { tryOnUnmounted } from '@vueuse/core';
 import { createLoading } from './createLoading';
 import type { LoadingProps } from './typing';
-import type { Ref } from 'vue';
 
 export interface UseLoadingOptions {
   target?: any;
@@ -45,5 +46,9 @@ export function useLoading(
     instance.setTip(tip);
   };
 
+  tryOnUnmounted(() => {
+    instance.destory();
+  });
+
   return [open, close, setTip];
 }

+ 1 - 1
src/directives/loading.ts

@@ -28,7 +28,7 @@ const loadingDirective: Directive = {
     }
   },
   unmounted(el) {
-    el?.instance?.close();
+    el?.instance?.destory();
   },
 };