Skip to content

fix(Touch directive): prevent memory leak when parent: true and element is detached - #23065

Open
waterWang wants to merge 1 commit into
vuetifyjs:masterfrom
waterWang:fix/touch-memory-leak-unmounted-parent
Open

fix(Touch directive): prevent memory leak when parent: true and element is detached#23065
waterWang wants to merge 1 commit into
vuetifyjs:masterfrom
waterWang:fix/touch-memory-leak-unmounted-parent

Conversation

@waterWang

Copy link
Copy Markdown
Contributor

Description

When the Touch directive is used with parent: true, the unmounted hook attempts to find the target via el.parentElement. However, by the time unmounted fires, the element may already be detached from the DOM, making parentElement null. This causes the cleanup of event listeners and _touchHandlers to be skipped entirely, leaking memory.

Root Cause

In packages/vuetify/src/directives/touch/index.ts, the unmounted function re-derives the target element from the DOM:

const target = binding.value?.parent ? el.parentElement : el

When parent: true and the element is detached (e.g. inside a v-if/router transition), el.parentElement returns null, so no cleanup runs.

Fix

  1. Store the target reference on the directive element during mounted so it's available in unmounted regardless of DOM attachment state.
  2. Store the addEventListener options alongside the target and pass them to removeEventListener for correct matching when custom options (e.g. capture: true) are used.
  3. Clean up the stored references in unmounted.

Changes

  • packages/vuetify/src/directives/touch/index.ts — store target + options in mounted, use stored values in unmounted
  • packages/vuetify/src/globals.d.ts — add _touchTarget and _touchOptions to the HTMLElement interface

Closes #21887

…nt is detached

When the Touch directive is used with parent: true, the unmounted
hook attempts to find the target via el.parentElement. However, by
the time unmounted fires, the element may already be detached from
the DOM, making parentElement null. This causes the cleanup of
event listeners and _touchHandlers to be skipped entirely, leaking
memory.

Fix: store the resolved target element reference and add/remove
options on the directive element during mounted, and use the stored
values in unmounted instead of re-deriving them from the DOM.

Also pass the correct options to removeEventListener so that
listeners registered with custom capture: true are properly removed.

Closes vuetifyjs#21887
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug Report][3.9.4] Memory leak in Touch directive

1 participant