Vue Event Modifiers
Event modifiers are dot-suffixes added to v-on bindings that handle common event-handling chores, like preventing default browser behavior, directly in the template.
What Are Event Modifiers
Without modifiers, tasks like calling event.preventDefault() or event.stopPropagation() have to happen inside the handler function itself, mixing DOM plumbing in with your actual logic. Event modifiers move that plumbing into the template as a dot-suffix on the event name, keeping methods focused purely on what should happen.
Preventing a form's default submit
<div id="app">
<form @submit.prevent="onSubmit">
<input v-model="email" placeholder="Email" />
<button type="submit">Subscribe</button>
</form>
<p v-if="submitted">Thanks, {{ email }}!</p>
</div>
<script>
const app = Vue.createApp({
data() {
return { email: '', submitted: false }
},
methods: {
onSubmit() {
this.submitted = true
}
}
})
app.mount('#app')
</script>.stop and .once
.stop calls event.stopPropagation(), preventing the event from bubbling up to parent elements, which is useful when a nested clickable element shouldn't also trigger a handler on its container. .once removes the listener automatically after it fires a single time, handy for things like a one-time dismissible banner.
Using .stop and .once together
<div id="app">
<div @click="closePanel" class="overlay">
<div @click.stop="noop" class="panel">
<p>Click outside this box to close.</p>
<button @click.once="claimBonus">Claim welcome bonus</button>
</div>
</div>
</div>
<script>
const app = Vue.createApp({
methods: {
closePanel() {
console.log('Panel closed')
},
noop() {},
claimBonus() {
console.log('Bonus claimed - this only ever runs once')
}
}
})
app.mount('#app')
</script>- .prevent - calls event.preventDefault()
- .stop - calls event.stopPropagation()
- .self - only triggers if the event originated on the element itself, not a child
- .capture - uses the capture phase instead of the bubble phase
- .once - the listener fires at most one time
- .passive - tells the browser the handler won't call preventDefault, improving scroll performance
Key Modifiers
Keyboard events can be filtered down to a specific key using a key modifier, so a handler only fires when that key was the one pressed. This avoids the common pattern of checking event.key manually inside every keyup or keydown handler. System modifier keys like ctrl, alt, shift, and meta can also be combined onto other events, including click.
Enter to search, Ctrl+Click to open in a new context
<div id="app">
<input
v-model="query"
@keyup.enter="runSearch"
placeholder="Press Enter to search"
/>
<a href="#" @click.ctrl.prevent="openInNewTab">Docs</a>
</div>
<script>
const app = Vue.createApp({
data() {
return { query: '' }
},
methods: {
runSearch() {
console.log('Searching for:', this.query)
},
openInNewTab() {
console.log('Ctrl+Click detected, opening in a new tab')
}
}
})
app.mount('#app')
</script>Exercise: Vue Event Modifiers
What does the .prevent modifier do when added to an event listener?