Vue · VUE0025

Prefer VueUse event listener cleanup

Finds Vue scopes that manually pair DOM event listener setup and cleanup when VueUse is already available.
VUE0025vite-doctor/vuelifecyclewarnSuggestion

Run this rule

pnpm vite-doctor . --framework vue --rules vue/lifecycle/prefer-use-event-listener

Why it matters

DOM listeners are lifecycle resources. Keeping setup and disposal behind a composable makes repeated watcher runs, component unmounts, and composable scope disposal harder to drift apart.

Use VueUse useEventListener() for DOM listeners. In watcher callbacks, keep the returned stop handle in watcher cleanup when each watcher run owns a fresh listener.

Example

Use VueUse for watcher-owned listeners

Before

watch(active, (_value, _oldValue, onCleanup) => {
  const el = document.querySelector('.target')
  if (!el) return
  const onEnd = () => el.classList.remove('active')
  el.addEventListener('animationend', onEnd, { once: true })
  onCleanup(() => el.removeEventListener('animationend', onEnd))
})

After

watch(active, (_value, _oldValue, onCleanup) => {
  const el = document.querySelector('.target')
  if (!el) return
  const stop = useEventListener(el, 'animationend', () => {
    el.classList.remove('active')
  }, { once: true })
  onCleanup(stop)
})
Copyright © 2026