Reputation: 20920
I have a Button.vue
looks like this. I'm using v-on="$listeners"
to pass all listeners to <a>
.
<template>
<a
v-bind="$attrs"
v-on="$listeners"
class="Button"
href="javascript: void(0)"
:class="{ disabled }"
@click="onClick()"
>
<slot></slot>
</a>
</template>
<script>
export default {
props: {
disabled: {
type: Boolean,
default: false
}
},
methods: {
onClick() {
if (!this.disabled) {
this.$emit('click');
}
}
},
};
</script>
But I need a custom check before propagating the @click
event, so I also defined @click
.
But when I define both v-on="$listeners"
and @click="onClick()"
at the same time, the onClickDelete
function get called twice. I also tried @click.prevent
, but still doesn't work.
<Button @click="onClickDelete">Delete</Button>
Is there a way I can define v-on="$listeners"
for all the events except @click
?
Here's the code sandbox.
Upvotes: 6
Views: 12688
Reputation: 138696
You could create a copy of $listeners
(by spreading it into a new object), and overwrite click
:
<a v-on="{ ...$listeners, click: () => {} }">
Or create a computed prop that excludes any click
event handler:
export default {
computed: {
myListeners() {
const { click, ...listeners } = this.$listeners // exclude `click`-listener
return listeners
},
},
}
Then bind that prop to v-on
in place of $listeners
:
<a v-on="myListeners">
Upvotes: 24