Vue Event Handling with v-on
In Vue, the v-on
directive
is how you run JavaScript in response to DOM events. If you want to
run some code when the user clicks a button, you should use v-on
.
For example, suppose you want to reset an input field to its default
value every time the user clicks a "Reset" button. The way to execute
a JavaScript expression when the user clicks a button is using the
v-on:click
directive as shown below.
const app = new Vue({
data: () => ({ value: 'Hello, World' }),
template: `
<div id="rendered-content">
<div><input v-model="value"></input></div>
<button v-on:click="value = 'Hello, World'">
Reset
</button>
</div>
`
});
Everything after v-on:
is the name of the event Vue will listen to.
So v-on:click
tells Vue to register a listener for the native 'click' event.
There's nothing special about the 'click' event. You can use v-on:
to listen to any native event, like:
@
Shorthand
Vue has a convenient shorthand for v-on
:
the @
symbol. For example, @click
is functionally equivalent to
v-on:click
. Using @
saves you a few keystrokes, but v-on
is more
readable for people who aren't familiar with Vue.
const app = new Vue({
data: () => ({ value: 'Hello, World' }),
// Uses `@click` instead of `v-on:click`
template: `
<div id="rendered-content">
<div><input v-model="value"></input></div>
<button @click="value = 'Hello, World'">
Reset
</button>
</div>
`
});
Many Vue codebases use @
, so you should be familiar with it. However,
you should prefer to use v-on
for readability, unless you have a
large codebase that you only expect experienced Vue developers to work
with.
With Custom Components
Using $emit
to send events to parent components is a core tenant of data flow in Vue.
Even v-model
uses v-on
under the hood.
In Vue methods and expressions, you have access to a $emit()
function
that lets you emit an event up the component tree to the parent
component. In the below example, the input-name
component emits a
'update' event. The top-level app listens for 'update' events using
v-on:update
, and changes the name accordingly.
Vue.component('input-name', {
data: () => ({ name: 'World' }),
// When you click the "Update" button, Vue will emit an event `update`
// to the parent, with the current state of 'name'.
template: `
<div>
<input type="text" v-model="name">
<button v-on:click="$emit('update', name)">
Update
</button>
</div>
`
});
const app = new Vue({
data: () => ({ name: 'World' }),
// To listen to the 'update' event, you create the `input-name`
// component with a `v-on:update` attribute. `$event` contains
// the value of the 2nd parameter to `$emit()`.
template: `
<div>
<div>
<input-name v-on:update="setName($event)"></input-name>
</div>
<h1>Hello, {{name}}</h1>
</div>
`,
methods: {
// Define a method that Vue will call to handle the 'update' event.
setName: function(v) {
this.name = v;
}
}
});
app.$mount('#content');