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; }