diff --git a/src/_utils/composable/use-resize.ts b/src/_utils/composable/use-resize.ts index fad8fb8cea5..a0ea3977d17 100644 --- a/src/_utils/composable/use-resize.ts +++ b/src/_utils/composable/use-resize.ts @@ -1,9 +1,19 @@ import { onBeforeUnmount, onMounted, type Ref } from 'vue' import { resizeObserverManager } from 'vueuc' +interface UseOnResizeOptions { + /** + * In some cases + * if a reactive variable is used in the render function to control whether or not the dom is rendered, + * the event cannot be cleared in onBeforeUnmount because the dom no longer exists, + * but the event contains a reference to the dom, resulting in a memory leak + */ + show?: Ref +} export function useOnResize( elRef: Ref, - onResize: (() => void) | undefined + onResize: (() => void) | undefined, + options?: UseOnResizeOptions ): void { // it needn't be reactive since it's for internal usage if (onResize) { @@ -19,5 +29,14 @@ export function useOnResize( resizeObserverManager.unregisterHandler(el) } }) + if (options?.show && isRef(options.show)) { + onBeforeUpdate(() => { + const { value: el } = elRef + const { value: show } = options.show! + if (!show && el) { + resizeObserverManager.unregisterHandler(el) + } + }) + } } } diff --git a/src/cascader/src/CascaderMenu.tsx b/src/cascader/src/CascaderMenu.tsx index 6252395aba2..e32c06df7f8 100644 --- a/src/cascader/src/CascaderMenu.tsx +++ b/src/cascader/src/CascaderMenu.tsx @@ -13,6 +13,7 @@ import { inject, type PropType, ref, + toRef, Transition, withDirectives } from 'vue' @@ -74,7 +75,7 @@ export default defineComponent({ function handleResize(): void { syncCascaderMenuPosition() } - useOnResize(selfElRef, handleResize) + useOnResize(selfElRef, handleResize, { show: toRef(props, 'show') }) function showErrorMessage(label: string): void { const { value: { loadingRequiredMessage }