Reputation: 12207
The docs say
<a @click="doSomething"> ... </a>
is short-hand for
<a v-on:click="doSomething"> ... </a>
Why does this short-hand not work in all cases? For example,
<v-dialog v-model="dialog" width="500">
<template v-slot:activator="{ on }">
<v-btn dark v-on="on">Working button</v-btn>
<v-spacer />
<v-btn dark @on="on">Non-working button</v-btn>
</template>
<v-card>
<v-card-title>Some Dialog</v-card-title>
<v-card-text>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
</v-card-text>
</v-card>
</v-dialog>
The "Working button" works, but the "Non-working button" doesn't. It seems like the v-on
shorthand only works for events. But if that's true, I haven't seen it documented.
I'm using Vuetify in this example, but my question is about Vue.js in general.
Here's a CodePen of above: https://codepen.io/keeganwitt/pen/bGGVeZY
Upvotes: 3
Views: 2995
Reputation: 55644
So, @on
in your example is shorthand for v-on:on
, meaning that the event handler is listening for the child component to emit an on
event. The v-btn
component does not ever emit an on
event, so nothing ever happens.
This isn't the thrust of your question, but you technically can use the v-on
shorthand to bind to an on
event:
Vue.config.devtools = false;
Vue.config.productionTip = false;
Vue.component('toggle', {
template: `
<button @click="onClick">
{{ isOn ? 'On' : 'Off' }}
</button>
`,
data() {
return {
isOn: false
};
},
methods: {
onClick() {
this.isOn = !this.isOn;
if (this.isOn) {
this.$emit('on');
} else {
this.$emit('off');
}
}
}
});
new Vue({
el: '#app',
methods: {
alert(val) {
alert(val);
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<toggle @on="alert('on')" @off="alert('off')"/>
</div>
I think what is confusing you is the v-on="on"
syntax. It's not obvious from the code, but the on
variable being set as the value for v-on
in this case is not a function, but an object.
Starting in 2.4.0+, v-on also supports binding to an object of event/listener pairs without an argument. Note when using the object syntax, it does not support any modifiers.
So the on
variable in this case probably looks something like this:
{ click: onClick, mouseover: onMouseover }
Passing all of the event listeners this way allows for less boilerplate code. The way you would need to do this before v2.4 was like this:
<template v-slot:activator="{ onClick, onMouseover }">
<v-btn
dark
@click="onClick"
@mouseover="onMouseover"
>
Working button
</v-btn>
</template>
Upvotes: 2
Reputation: 5075
v-on:click
short hand is @click
not @on
so you can use @click
instead of v-on="on"
. But here slotProp on
is an Object with click
(function) property. so you can use it like below
<v-btn dark @click="on.click">Now working button</v-btn>
but it is recommended to use v-on="on"
since there could be multiple properties under on
Object
Ex: if on
is { click: fn(), mouseup: fn() }
<v-btn dark @click="on.click" @mouseup="on.mouseup" >Now working button</v-btn>
<!-- same as -->
<v-btn dark v-on="on">Now working button</v-btn>
Upvotes: 3