Vue 3+Inertia是否会在组件卸载时自动删除事件侦听器



我在script setup:中有一个事件侦听器

<script setup>
import {ref} from 'vue'
const elementRef = ref(null)

window.addEventListener('click', (event) => {
if (!elementRef.value.contains(event.target)){
console.log('click outside element')
}
})
</script>

<template>
<div ref="elementRef">your element</div>
</template>

卸载组件时会将其删除吗?还是必须手动删除?

全局事件侦听器不会自动删除,因此您的组件需要显式删除。

您应该在mounted钩子中添加侦听器,并在unmounted钩子中删除它。此外,您还需要存储传递给addEventListener的函数,以便将其传递给removeEventListener:

<script setup>
import { ref, onMounted, onUnmounted } from 'vue'
const elementRef = ref(null)
const onClick = (event) => {
if (!elementRef.value.contains(event.target)) {
console.log('click outside element')
}
}
onMounted(() => window.addEventListener('click', onClick))
onUnmounted(() => window.removeEventListener('click', onClick))
</script>

我找到了一种自动注销事件侦听器的方法:

import { getCurrentScope, onScopeDispose } from "vue";
export function addEventListenerWrapper(target, name, fn) {
target.addEventListener(name, fn);
if (getCurrentScope()) {
onScopeDispose(() => target.removeEventListener(name, fn));
}
}

然后你应该能够像这样在你的组件中注册你的监听器,它应该稍后自动注销:

addEventListenerWrapper(window, "click", event => {
if (!elementRef.value.contains(event.target)) {
console.log("click outside element");
}
})

请参阅下面的Vue SFC游乐场,以了解其运行情况。您应该在控制台中看到,使用按钮切换元素将导致控制台打印事件注册/注销消息。

查看这些链接了解更多信息:

  • https://vuejs.org/api/reactivity-advanced.html#onscopedispose
  • https://github.com/vuejs/pinia/blob/78ec9a186dcbce3d583db332ae22094a182358cc/packages/pinia/src/subscriptions.ts

最新更新