在 Vue 中,$emit 用于觸發(fā)事件,而事件監(jiān)聽器是通過 $on 或 v-on (@) 綁定的。要移除由 $emit 觸發(fā)的事件監(jiān)聽器,核心是移除對應(yīng)的事件綁定,而非直接操作 $emit。以下是具體實(shí)現(xiàn)方法及場景說明:
$emit:觸發(fā)組件實(shí)例上的事件,通知父組件或其他監(jiān)聽者。
- 事件監(jiān)聽器:通過
$on 或 v-on 綁定的回調(diào)函數(shù),用于響應(yīng)事件。
- 移除監(jiān)聽器:需針對綁定方式,使用
$off 或銷毀組件來移除。
如果事件是通過 $on 動態(tài)綁定的,使用 $off 移除。
export default {
created() {
this.handleClick = () => {
console.log('事件觸發(fā)');
};
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('事件觸發(fā)');
</script>
通過 重新渲染組件 實(shí)現(xiàn)事件解綁。
<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('事件觸發(fā)');
</script>
當(dāng) componentKey 變化時,組件會重新創(chuàng)建,舊的事件綁定會被銷毀。
<!-- 父組件 -->
<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']);
// 觸發(fā)事件
const trigger = () => {
emit('child-event', 'hello');
};
</script>
父組件如需移除監(jiān)聽,可通過銷毀子組件(v-if)或重新渲染(key)實(shí)現(xiàn)。
<script setup>
import { onMounted, onUnmounted, ref } from 'vue';
const myComponent = ref(null);
let count = 0;
// 定義事件處理函數(shù)
const handleCustomEvent = () => {
count++;
console.log('事件觸發(fā)次數(shù):', count);
};
onMounted(() => {
// 動態(tài)綁定事件
myComponent.value.$on('custom-event', handleCustomEvent);
});
onUnmounted(() => {
// 移除事件監(jiān)聽
myComponent.value.$off('custom-event', handleCustomEvent);
});
</script>
$emit 是觸發(fā)事件,不是綁定事件,無法直接移除 $emit,只能移除對應(yīng)的監(jiān)聽器。
- 若通過
v-on 綁定事件,Vue 會在組件銷毀時自動移除,無需手動操作。
- 若事件是通過
$on 動態(tài)綁定的,必須用 $off 手動移除,否則可能導(dǎo)致內(nèi)存泄漏。
- 確保
$off 的參數(shù)(事件名、回調(diào)函數(shù))與 $on 完全一致,否則移除無效。
通過以上方法,可以有效移除由 $emit 觸發(fā)的事件監(jiān)聽器,避免內(nèi)存泄漏和不必要的事件響應(yīng)。 |