在 Vue 中,$emit 用于触发事件,而事件监听器是通过 $on 或 v-on (@) 绑定的。要移除由 $emit 触发的事件监听器,核心是移除对应的事件绑定,而非直接操作 $emit。以下是具体实现方法及场景说明:
$emit:触发组件实例上的事件,通知父组件或其他监听者。
- 事件监听器:通过
$on 或 v-on 绑定的回调函数,用于响应事件。
- 移除监听器:需针对绑定方式,使用
$off 或销毁组件来移除。
如果事件是通过 $on 动态绑定的,使用 $off 移除。
export default {
created() {
this.handleClick = () => {
console.log('事件触发');
};
this.$on('custom-event', this.handleClick);
},
methods: {
triggerEvent() {
this.$emit('custom-event');
},
removeListener() {
this.$off('custom-event', this.handleClick);
}
}
};
this.$off('custom-event');
如果事件是通过模板 @eventName 绑定的,有两种方式移除:
通过 v-if 控制组件销毁,Vue 会自动清理所有 v-on 绑定的事件。
<!-- 父组件 -->
<template>
<ChildComponent v-if="showChild" @custom-event="handleEvent" />
<button @click="showChild = false">销毁子组件</button>
</template>
<script setup>
import { ref } from 'vue';
import ChildComponent from './ChildComponent.vue';
const showChild = ref(true);
const handleEvent = () => console.log('事件触发');
</script>
通过 重新渲染组件 实现事件解绑。
<template>
<ChildComponent
:key="componentKey"
@custom-event="handleEvent"
/>
<button @click="componentKey += 1">解绑事件</button>
</template>
<script setup>
import { ref } from 'vue';
import ChildComponent from './ChildComponent.vue';
const componentKey = ref(0);
const handleEvent = () => console.log('事件触发');
</script>
当 componentKey 变化时,组件会重新创建,旧的事件绑定会被销毁。
<!-- 父组件 -->
<template>
<ChildComponent @child-event="handleChildEvent" />
</template>
<script setup>
import { ref } from 'vue';
import ChildComponent from './ChildComponent.vue';
const handleChildEvent = (data) => {
console.log('收到子组件事件:', data);
};
</script>
<!-- 子组件 ChildComponent.vue -->
<script setup>
import { emit } from 'vue';
const emit = defineEmits(['child-event']);
// 触发事件
const trigger = () => {
emit('child-event', 'hello');
};
</script>
父组件如需移除监听,可通过销毁子组件(v-if)或重新渲染(key)实现。
<script setup>
import { onMounted, onUnmounted, ref } from 'vue';
const myComponent = ref(null);
let count = 0;
// 定义事件处理函数
const handleCustomEvent = () => {
count++;
console.log('事件触发次数:', count);
};
onMounted(() => {
// 动态绑定事件
myComponent.value.$on('custom-event', handleCustomEvent);
});
onUnmounted(() => {
// 移除事件监听
myComponent.value.$off('custom-event', handleCustomEvent);
});
</script>
$emit 是触发事件,不是绑定事件,无法直接移除 $emit,只能移除对应的监听器。
- 若通过
v-on 绑定事件,Vue 会在组件销毁时自动移除,无需手动操作。
- 若事件是通过
$on 动态绑定的,必须用 $off 手动移除,否则可能导致内存泄漏。
- 确保
$off 的参数(事件名、回调函数)与 $on 完全一致,否则移除无效。
通过以上方法,可以有效移除由 $emit 触发的事件监听器,避免内存泄漏和不必要的事件响应。 |