在 Vue 中确保事件绑定与移除的参数完全一致,核心是 **“规范化事件绑定的参数管理,让绑定与移除使用同一套配置”**,避免因参数 mismatch 导致移除失效。以下是具体落地方法,覆盖原生 DOM 事件、Vue 自定义事件、第三方库事件等场景:
无论哪种事件类型,绑定与移除必须满足以下 3 点完全匹配:
-
事件类型:如 click、scroll、custom-event 等字符串完全一致;
-
回调函数引用:必须是同一个函数(不能用匿名函数、每次渲染重新创建的函数);
-
可选参数:如原生事件的 useCapture(捕获阶段)、第三方库的事件配置,需完全一致。
原生事件容易因 “回调引用不一致”“遗漏 useCapture” 出错,需通过「具名函数 + 统一配置」解决。
<script setup>
import { onMounted, onUnmounted, ref } from 'vue';
const boxRef = ref(null);
// 1. 定义具名回调函数(确保引用唯一)
function handleClick(e) {
console.log('点击事件触发');
}
function handleScroll(e) {
console.log('滚动事件触发');
}
// 2. 统一存储事件配置(类型 + 回调 + 可选参数)
const eventConfig = [
{ type: 'click', handler: handleClick, useCapture: false },
{ type: 'scroll', handler: handleScroll, useCapture: true } // 捕获阶段
];
// 3. 绑定事件:遍历配置
onMounted(() => {
if (boxRef.value) {
eventConfig.forEach(({ type, handler, useCapture }) => {
boxRef.value.addEventListener(type, handler, useCapture);
});
}
});
// 4. 移除事件:遍历同一配置(参数自动一致)
onUnmounted(() => {
if (boxRef.value) {
eventConfig.forEach(({ type, handler, useCapture }) => {
boxRef.value.removeEventListener(type, handler, useCapture);
});
}
});
</script>
错误示例(每次渲染创建新函数,引用不一致):
boxRef.value.addEventListener('click', () => handleClick()); boxRef.value.removeEventListener('click', () => handleClick());
正确示例(用具名函数或 useCallback 缓存):
const handleClick = useCallback((e) => { console.log('点击事件触发'); }, []);
Vue 组件实例的自定义事件,需确保「事件名 + 回调函数引用」一致,核心是避免匿名函数绑定。
<script>
export default {
created() {
// 1. 定义具名回调(或绑定到 this 上)
this.handleCustomEvent = (data) => {
console.log('自定义事件触发:', data);
};
// 2. 绑定事件(用 this 上的函数引用)
this.$on('custom-event', this.handleCustomEvent);
},
beforeDestroy() {
// 3. 移除事件(引用与绑定完全一致)
this.$on('custom-event', this.handleCustomEvent);
}
};
</script>