From bb443a05e2496442111c15182d93798a6683ef2e Mon Sep 17 00:00:00 2001
From: tangjinzhou <415800467@qq.com>
Date: Fri, 13 Sep 2024 19:05:04 +0800
Subject: [PATCH] fix: button wave memory leak
---
components/_util/wave/WaveEffect.tsx | 6 ++++++
components/_util/wave/index.tsx | 3 +--
components/_util/wave/useWave.ts | 14 +++++++++-----
3 files changed, 16 insertions(+), 7 deletions(-)
diff --git a/components/_util/wave/WaveEffect.tsx b/components/_util/wave/WaveEffect.tsx
index 1f3ce23d1..b59c8ff66 100644
--- a/components/_util/wave/WaveEffect.tsx
+++ b/components/_util/wave/WaveEffect.tsx
@@ -159,6 +159,12 @@ function showWaveEffect(node: HTMLElement, className: string) {
node?.insertBefore(holder, node?.firstChild);
render(, holder);
+ return () => {
+ render(null, holder);
+ if (holder.parentElement) {
+ holder.parentElement.removeChild(holder);
+ }
+ };
}
export default showWaveEffect;
diff --git a/components/_util/wave/index.tsx b/components/_util/wave/index.tsx
index 26ac1aff5..26dab40f9 100644
--- a/components/_util/wave/index.tsx
+++ b/components/_util/wave/index.tsx
@@ -33,13 +33,12 @@ export default defineComponent({
// =============================== Wave ===============================
const showWave = useWave(
- instance,
computed(() => classNames(prefixCls.value, hashId.value)),
wave,
);
let onClick: (e: MouseEvent) => void;
const clear = () => {
- const node = findDOMNode(instance);
+ const node = findDOMNode(instance) as HTMLElement;
node.removeEventListener('click', onClick, true);
};
onMounted(() => {
diff --git a/components/_util/wave/useWave.ts b/components/_util/wave/useWave.ts
index 84e2a6eff..f88c36168 100644
--- a/components/_util/wave/useWave.ts
+++ b/components/_util/wave/useWave.ts
@@ -1,21 +1,25 @@
-import type { ComponentInternalInstance, ComputedRef, Ref } from 'vue';
+import type { ComputedRef, Ref } from 'vue';
+import { onBeforeUnmount, getCurrentInstance } from 'vue';
import { findDOMNode } from '../props-util';
import showWaveEffect from './WaveEffect';
export default function useWave(
- instance: ComponentInternalInstance | null,
className: Ref,
wave?: ComputedRef<{ disabled?: boolean }>,
): VoidFunction {
+ const instance = getCurrentInstance();
+ let stopWave: () => void;
function showWave() {
const node = findDOMNode(instance);
-
+ stopWave?.();
if (wave?.value?.disabled || !node) {
return;
}
-
- showWaveEffect(node, className.value);
+ stopWave = showWaveEffect(node, className.value);
}
+ onBeforeUnmount(() => {
+ stopWave?.();
+ });
return showWave;
}