I have a Vue2 ponent which contains an added eventListener i created on mounted
. I was wondering how do i properly remove this listener when the ponent is destroyed?
<template>
<div>
...
</div>
</template>
<script>
export default {
mounted() {
window.addEventListener('click', (evt) => {
this.handleClickEvent(evt)
})
},
destroyed() {
// window.removeEventListener('click', ????);
},
methods: {
handleClickEvent(evt) {
// do stuff with (evt)
},
},
}
</script>
I have a Vue2 ponent which contains an added eventListener i created on mounted
. I was wondering how do i properly remove this listener when the ponent is destroyed?
<template>
<div>
...
</div>
</template>
<script>
export default {
mounted() {
window.addEventListener('click', (evt) => {
this.handleClickEvent(evt)
})
},
destroyed() {
// window.removeEventListener('click', ????);
},
methods: {
handleClickEvent(evt) {
// do stuff with (evt)
},
},
}
</script>
Share
Improve this question
edited Dec 8, 2022 at 22:54
Nikola Pavicevic
23.5k9 gold badges29 silver badges51 bronze badges
asked Jan 15, 2022 at 23:56
JokerMartiniJokerMartini
6,14712 gold badges102 silver badges221 bronze badges
2 Answers
Reset to default 4You have to keep a reference to the registered click handler, in order to be able to remove it later:
mounted() {
this.clickHandler = () => { ... };
window.addEventListener('click', this.clickHandler);
}
beforeDestroy() {
window.removeEventListener('click', this.clickHandler);
}
However, you seem to already have this function defined in the ponent. It's named handleClickEvent
. So there's no reason to create an arrow function wrapper around it. You can use it directly:
mounted() {
window.addEventListener('click', this.handleClickEvent);
}
beforeDestroy() {
window.removeEventListener('click', this.handleClickEvent);
}
Another neat feature available in vue2 (and, sadly, not in vue3) is to dynamically register a hook, which allows adding and removing the handler in mounted()
, without the need of keeping a reference to it in the ponent:
mounted() {
const handler = () => { ... }; // local variable
window.addEventListener('click', handler);
this.$once('hook:beforeDestroy',
() => window.removeEventListener('click', handler)
);
}
https://v2.vuejs/v2/guide/ponents-edge-cases.html#Programmatic-Event-Listeners
You can use this.$el
for whole ponent and destroy event like you created it:
Vue.ponent('Child', {
template: `
<div class="child">
click for event
</div>
`,
mounted() {
this.$el.addEventListener('click', (evt) => {
this.handleClickEvent(evt)
})
},
beforeDestroy() {
console.log('distroyed')
this.$el.removeEventListener('click', (evt) => {
this.handleClickEvent(evt)
})
},
methods: {
handleClickEvent(evt) {
console.log(evt.currentTarget)
// do stuff with (evt)
},
},
})
new Vue({
el: "#demo",
data() {
return {
show: true
}
},
methods: {
toggleShow() {
this.show = !this.show
}
}
})
.child {
height: 150px;
width: 200px;
background: goldenrod;
}
<script src="https://cdnjs.cloudflare./ajax/libs/vue/2.5.17/vue.js"></script>
<div id="demo">
<div>
<button @click="toggleShow">mount/unmount ponent</button>
<Child v-if="show" />
</div>
</div>