🚀 LEVEL UP TO SENIOR:Unlock 500+ Advanced Practical Challenges & Exercises.
🎓 COURSERA PARTNER:Earn professional Google, Meta, and IBM certificates to supercharge your resume.
HTML MASTER CLASS /// LEARN TAGS /// BUILD STRUCTURE /// SEMANTIC WEB /// HTML MASTER CLASS /// LEARN TAGS ///

Methods & Event Handling in Vue.js

Learn about Methods & Event Handling in this comprehensive Vue.js tutorial. Learn how to handle DOM events, use the @ shorthand, and leverage powerful event modifiers.

Total XP: 0|💻 vuejs XP: 0

Skill Matrix

UNLOCK NODES BY LEARNING NEW TAGS.

Select an unlocked node to view details root

🚀 LEVEL UP TO SENIOR:Unlock 500+ Advanced Practical Challenges & Exercises.
🎓 COURSERA PARTNER:Earn professional Google, Meta, and IBM certificates to supercharge your resume.

Respond to user actions with methods and event listeners.

1Listening to Events

Vue uses the v-on directive to listen to DOM events and run JavaScript when they're triggered. Because v-on is used so frequently, it has a dedicated shorthand: @. For example, v-on:click becomes @click.

2Methods in Composition API

In the Composition API (<script setup>), a method is simply a standard JavaScript function. You don't need a special methods object like in the Options API. Just write function doWork() {} and call it in your template.

3Event Modifiers

Calling event.preventDefault() or event.stopPropagation() is extremely common. Vue provides modifiers like .prevent and .stop directly in the template (@click.stop) so your JavaScript functions don't have to deal with DOM event details.

4Step-by-Step Breakdown

A reactive app needs to respond to the user! We do this using methods and event listeners.

In standard HTML, you use onclick="myFunction()". In Vue, we use the v-on directive, which is almost always abbreviated as @.

What is the shorthand syntax for the v-on:click event listener in Vue?

  • v-
  • #
  • @

Inside <script setup>, a "method" is literally just a standard JavaScript function.

You can pass arguments to your methods directly from the template, just like normal JavaScript.

How do you call a method named deleteItem and pass it the id of 5 when a button is clicked?

  • deleteItem(5)
  • deleteItem:5
  • deleteItem=5

Vue provides Event Modifiers. Need to call event.preventDefault()? Just add .prevent to the event!

Need to listen to a specific key, like Enter? Use the .enter modifier.

Which event modifier prevents the default behavior of an event (like a form submission refreshing the page)?

  • stop
  • prevent
  • halt

Methods and modifiers keep your JavaScript clean. Your functions focus on logic, while the template handles the DOM event nuances.

Level Up 🚀

Advanced cheat sheets, SEO tricks, and interview prep for this topic.

Browser Support

ChromeSupported

Fully supported.

FirefoxSupported

Fully supported.

SafariSupported

Fully supported.

EdgeSupported

Fully supported.

Accessibility (A11y)

1Handling Both Click and Keyboard Activation

Native elements like <button> already fire @click on both mouse click and Enter/Space key press, but a custom element like a <div> wired with @click needs an explicit @keydown.enter handler and tabindex="0" to be operable without a mouse.

<div role="button" tabindex="0" @click="toggle" @keydown.enter="toggle">Toggle</div>

SEO Implications

  • 1

    Event Handlers Carry No SEO Weight, But What They Gate Does

    Content that only becomes visible after a @click interaction (an accordion body) is still present in the rendered DOM if it's just CSS-hidden with v-show, so crawlers that execute JavaScript can still index it — but if the same content is created lazily inside the handler itself (v-if plus a fetch call), it never exists until a real click happens.

Best Practices

Use Modifiers Instead of Manual Event Object Handling

Prefer the built-in @submit.prevent or @click.stop over writing (event) => { event.preventDefault(); ... } inside a method body — the modifier keeps the method function focused purely on business logic instead of DOM event mechanics.

Frequent Bugs

THE BUG

Forgetting .prevent on a form submit handler.

THE FIX

Without @submit.prevent, clicking a submit button inside a <form> triggers the browser's native form submission (a full page reload) in addition to your Vue handler, wiping out client-side state. Always pair @submit with .prevent unless you specifically want the native browser submission.

Real-World Examples

Debounced Search Input

A live search box calls a method on @input, but wraps it with a debounce utility so the API is only called 300ms after the user stops typing, rather than on every keystroke.

import { debounce } from 'lodash-es';
const search = debounce((e) => fetchResults(e.target.value), 300);

Interview Prep

?Frequently Asked Questions

Pascual Vila

Pascual Vila

Frontend Instructor // Code Syllabus

Common Pitfalls & Errors

The Error //

Mutating a Prop Directly

// Wrong const props = defineProps(['count']); function increment() { props.count++; } // Correct const emit = defineEmits(['update:count']); function increment() { emit('update:count', props.count + 1); }

The Solution //

A child component should never assign to a prop it received (e.g. props.title = 'New'). Vue logs "Unexpected mutation of prop" because props are a one-way binding. Copy the prop into local state with ref()/computed() first, or emit an event asking the parent to change its own data.

The Error //

Losing Reactivity by Destructuring reactive()

// Wrong const { name } = reactive({ name: 'Alice' }); // name is now a static string // Correct const state = reactive({ name: 'Alice' }); const { name } = toRefs(state); // name is a live ref

The Solution //

Destructuring a reactive() object copies its properties out as disconnected plain values, so future mutations of the original object won't update the destructured variables. Keep referencing the object's properties directly, or convert it with toRefs() before destructuring.

Continue Learning