Check if a component has an event listener attached to it
Solution 1
When there are listeners attached to a component they are available in the $listeners
property of the component.
You can use that property to determine if a specific listener is available. For example, here is a computed property that checks for the existence of a cancel
listener.
computed:{
hasCancelListener(){
return this.$listeners && this.$listeners.cancel
}
}
And here is an example of that used in a component.
console.clear()
Vue.component("CustomForm", {
template:`
<div>
<h1>Custom Form</h1>
<button v-if="hasCancelListener" @click="$emit('cancel')">I have a listener!</button>
</div>
`,
computed:{
hasCancelListener(){
return this.$listeners && this.$listeners.cancel
}
},
})
new Vue({
el: "#app",
methods:{
onCancel(){
alert('canceled')
}
}
})
<script src="https://unpkg.com/[email protected]"></script>
<div id="app">
<custom-form @cancel="onCancel"></custom-form>
<hr>
<custom-form></custom-form>
</div>
Solution 2
In Vue 3, the $listeners
object has been removed. The listeners are now part of the $attrs
object and are prefixed with on
.
In order to check if a particular listener is present or not in a child component, you can do:
computed: {
hasCancelListener() : boolean {
return (this.$attrs && this.$attrs.onCancel) as boolean
}
}
The child component is called as:
<custom-form @cancel="onCancel"></custom-form>
Kasheftin
Updated on June 27, 2022Comments
-
Kasheftin almost 2 years
Assuming there's some
<Form>
component. It can be called with a@cancel
event listener attached to it and if it's the case, I want to show the cancel button that triggers this event. If there's no@cancel
event, the cancel button should not be visible.Is there a way to check if a component has event listener attached to it?
Currently I do:
<template> <form> <button v-if="cancelEventPassed" @click="$emit('cancel')">Cancel</button> </form> </template>
And call it like this:
<Form :cancelEventPassed="true" @cancel="handle_cancel" />
either
<Form/>
Is it possible to achieve this without using any additional property like
cancelEventPassed
?