在 Vue 中,通過(guò) $on 方法動(dòng)態(tài)添加的事件監(jiān)聽(tīng)器,需要使用 $off 方法來(lái)移除。核心原則是:$off 的參數(shù)必須與 $on 完全匹配(事件名和回調(diào)函數(shù)引用一致)。以下是具體實(shí)現(xiàn)方法及場(chǎng)景示例:
$on 用于綁定事件,$off 用于移除,兩者參數(shù)對(duì)應(yīng)關(guān)系如下:
這是常用的場(chǎng)景,需確保 $off 的回調(diào)函數(shù)與 $on 引用一致(不能用匿名函數(shù))。
<script>
export default {
created() {
// 1. 定義具名回調(diào)函數(shù)(確保引用唯一)
this.handleClick = () => {
console.log('自定義事件被觸發(fā)');
};
// 2. 用 $on 綁定事件
this.$on('custom-click', this.handleClick);
},
mounted() {
// 模擬事件觸發(fā)
this.$emit('custom-click'); // 輸出:自定義事件被觸發(fā)
},
beforeDestroy() {
// 3. 用 $off 移除指定事件的指定回調(diào)(關(guān)鍵步驟)
this.$off('custom-click', this.handleClick);
}
};
</script>
若一個(gè)事件綁定了多個(gè)回調(diào),可通過(guò) $off('eventName') 一次性移除所有。
<script>
export default {
created() {
// 綁定多個(gè)回調(diào)到同一事件
this.$on('custom-event', () => console.log('回調(diào)1'));
this.$on('custom-event', () => console.log('回調(diào)2'));
},
mounted() {
this.$emit('custom-event'); // 輸出:回調(diào)1、回調(diào)2
},
beforeDestroy() {
// 移除 custom-event 的所有回調(diào)
this.$off('custom-event');
}
};
</script>
若需清空組件上所有通過(guò) $on 綁定的事件,直接調(diào)用 $off() 即可(無(wú)參數(shù))。
<script>
export default {
created() {
this.$on('event1', () => {});
this.$on('event2', () => {});
},
beforeDestroy() {
// 移除所有事件的所有回調(diào)
this.$off();
}
};
</script>
父組件通過(guò) v-on 綁定子組件的自定義事件,本質(zhì)是子組件內(nèi)部通過(guò) $on 處理,子組件可在卸載時(shí)用 $off 移除。
<!-- 子組件 Child.vue -->
<script>
export default {
created() {
// 父組件綁定的 @child-event 會(huì)被 Vue 內(nèi)部轉(zhuǎn)為 $on
// 子組件可通過(guò) $off 移除(需知道事件名和回調(diào))
this.$on('child-event', this.handleChildEvent);
},
methods: {
handleChildEvent() {
console.log('子組件事件觸發(fā)');
}
},
beforeDestroy() {
this.$off('child-event', this.handleChildEvent);
}
};
</script>
$on 若使用匿名函數(shù)綁定,$off 無(wú)法找到相同引用,導(dǎo)致移除失敗。
this.$on('custom-event', () => console.log('匿名回調(diào)'));
this.$off('custom-event', () => console.log('匿名回調(diào)'));
this.handleEvent = () => console.log('具名回調(diào)');
this.$on('custom-event', this.handleEvent);
this.$off('custom-event', this.handleEvent);
若 $on 綁定了多個(gè)回調(diào),$off('eventName', handler) 僅移除指定回調(diào),其他回調(diào)仍有效;若需移除所有,需用 $off('eventName')。
Vue 組件卸載時(shí),會(huì)自動(dòng)移除所有通過(guò) $on 綁定的事件監(jiān)聽(tīng)器,因此若僅需在組件銷毀時(shí)移除,無(wú)需手動(dòng)調(diào)用 $off。但如果組件未銷毀(如隱藏而非銷毀),則需手動(dòng)移除。
$on / $off 綁定的是組件實(shí)例的事件,而非 DOM 事件。若需移除 DOM 事件,仍需用 removeEventListener。
移除 $on 動(dòng)態(tài)添加的事件監(jiān)聽(tīng)器,核心是:
- 用
$off 方法,參數(shù)與 $on 完全匹配(事件名 + 回調(diào)函數(shù)引用);
- 避免使用匿名函數(shù),改用具名函數(shù)確保引用一致;
- 組件卸載時(shí) Vue 會(huì)自動(dòng)清理,無(wú)需手動(dòng)
$off(除非組件未銷毀);
- 區(qū)分組件實(shí)例事件(
$on / $off)和 DOM 事件(addEventListener / removeEventListener)。
|