Vue Event Modifiers

Control event behavior with simple modifiers

🎛️ What are Event Modifiers?

Event modifiers are special postfixes added to event directives that change how events behave. They handle common tasks like preventing default actions or stopping event propagation without writing extra JavaScript code.


<!-- Prevent form submission -->
<form @submit.prevent="handleSubmit">
  <button type="submit">Submit</button>
</form>
                                    

Output:

Common Event Modifiers

Vue provides several built-in event modifiers that make event handling cleaner and more intuitive. Instead of calling event.preventDefault() or event.stopPropagation() in your methods, you can simply add a modifier to your event directive. This makes your templates more declarative and easier to understand.

🛑

.prevent

Prevent default behavior

<form @submit.prevent>
  <!-- No page reload -->
</form>

.stop

Stop event propagation

<button @click.stop>
  Click
</button>
1️⃣

.once

Trigger event only once

<button @click.once>
  One Time
</button>
🎯

.self

Only trigger on element itself

<div @click.self>
  Click me only
</div>

🔹 .prevent Modifier

Prevent the default action (like form submission):

<template>
  <div>
    <form @submit.prevent="handleSubmit">
      <input v-model="username" placeholder="Username">
      <button type="submit">Submit</button>
    </form>
    <p>{{ message }}</p>
  </div>
</template>

<script setup>
import { ref } from 'vue'

const username = ref('')
const message = ref('')

function handleSubmit() {
  message.value = `Form submitted with: ${username.value}`
  // Page doesn't reload!
}
</script>

Output:

🔹 .stop Modifier

Stop event from bubbling to parent elements:

<template>
  <div @click="parentClick" style="padding: 20px; background: #f0f0f0;">
    <p>Parent Div (click me)</p>
    <button @click.stop="childClick">
      Child Button (click won't trigger parent)
    </button>
    <p>{{ clickInfo }}</p>
  </div>
</template>

<script setup>
import { ref } from 'vue'

const clickInfo = ref('')

function parentClick() {
  clickInfo.value = 'Parent clicked'
}

function childClick() {
  clickInfo.value = 'Child clicked (parent not triggered)'
}
</script>

Output:

Parent Div (click me)

🔹 .once Modifier

Event handler will only trigger once:

<template>
  <div>
    <button @click.once="showAlert">
      Click Me (Works Only Once)
    </button>
    <p>{{ status }}</p>
  </div>
</template>

<script setup>
import { ref } from 'vue'

const status = ref('Button not clicked yet')

function showAlert() {
  status.value = 'Button clicked! Try clicking again - nothing happens.'
}
</script>

Output:

Button not clicked yet

🔹 .self Modifier

Only trigger if event target is the element itself:

<template>
  <div 
    @click.self="handleClick" 
    style="padding: 30px; background: #e0e0e0;"
  >
    <p>Click the gray area (not this text)</p>
    <button>This button won't trigger the div click</button>
    <p>{{ result }}</p>
  </div>
</template>

<script setup>
import { ref } from 'vue'

const result = ref('')

function handleClick() {
  result.value = 'Div background clicked!'
}
</script>

Output:

Click the gray area (not this text)

🔹 Chaining Modifiers

Combine multiple modifiers together:

<template>
  <div>
    <!-- Prevent default AND stop propagation -->
    <a href="https://example.com" @click.prevent.stop="handleLink">
      Click Link
    </a>
    <p>{{ linkMessage }}</p>
  </div>
</template>

<script setup>
import { ref } from 'vue'

const linkMessage = ref('')

function handleLink() {
  linkMessage.value = 'Link clicked but navigation prevented!'
}
</script>

Output:

🔹 Key Modifiers

Special modifiers for keyboard events:

<template>
  <div>
    <input 
      @keyup.enter="submitOnEnter"
      @keyup.esc="clearInput"
      v-model="text"
      placeholder="Press Enter or Esc"
    >
    <p>{{ feedback }}</p>
  </div>
</template>

<script setup>
import { ref } from 'vue'

const text = ref('')
const feedback = ref('')

function submitOnEnter() {
  feedback.value = `Submitted: ${text.value}`
}

function clearInput() {
  text.value = ''
  feedback.value = 'Input cleared!'
}
</script>

Output:

🧠 Test Your Knowledge

Which modifier prevents the default browser behavior?