Vue Event Handling: A Complete Guide

We listen for events in an application in order to perform certain actions when they occur. For example, we can display content or fetch data when a button is clicked, a key is pressed, a text input value is changed, and so on. In this article, we’re going to learn how to handle events in Vue apps to enable interactivity.

Listening for Events in Vue

To listen for an event, we pass the handler to a v-on directive attached to an element, for example:

<button v-on:click="handler">Click me</button>

We can also use the @ symbol for a shorter syntax:

<button @click="handler">Click me</button>

There are two types of event handlers in Vue: inline handlers and method handlers.

Inline Event Handlers

To create an inline event handler, we pass inline JavaScript that will be executed when the event is triggered. For example:

<template>
  <p>Count: {{ count }}</p>
  <button @click="count++">Add 1</button>
</template>

<script>
export default {
  data() {
    return {
      count: 0,
    };
  },
};
</script>

Method Event Handlers

Method event handlers are what we use when we have more complex logic spanning multiple lines of code. We pass the name of a method defined on a Vue component to use it to handle the event.

For example:

<template>
  Count: {{ count }}
  <br />
  <button @click="increment">Add 1</button>
</template>

<script>
export default {
  data() {
    return {
      count: 0,
    };
  },
  methods: {
    increment() {
      this.count++;
      if (this.count % 5 === 0) {
        alert(`${this.count} is divisible by 5.`);
      }
    },
  },
};
</script>

Calling Methods in Inline Handlers

We can also call a method in an event handler directly. This is useful for passing arguments.

<template>
  <p>Count: {{ count }}</p>
  <button @click="increment(2)">Add 2</button>
  <button @click="increment(3)">Add 3</button>
</template>

<script>
export default {
  data() {
    return {
      count: 0,
    };
  },
  methods: {
    increment(amount) {
      this.count += amount;
      if (this.count % 5 === 0) {
        alert(`${this.count} is divisible by 5.`);
      }
    },
  },
};
</script>

Accessing Event Arguments in Event Handlers

When the name of a method is passed directly, the DOM event object associated with the event will be passed to the first parameter of the method:

<template>
  <button
    id="btn-1"
    @click="handleClick"
  >
    Button 1
  </button>
</template>

<script>
export default {
  methods: {
    handleClick(event) {
      const target = event.target;
      alert(`Button with ID ${target.id} clicked`);
    },
  },
};
</script>

We can also use an inline arrow function to access this event object:

<template>
  <button
    id="btn-1"
    @click="(event) => handleClick('Peter', event)"
  >
    Button 1
  </button>
</template>

<script>
export default {
  methods: {
    handleClick(username, event) {
      const target = event.target;
      alert(
        `${username} clicked the button with ID ${target.id}`
      );
    },
  },
};
</script>

Or we could pass the special $event variable when calling the method from the inline handler:

<template>
  <button
    id="btn-1"
    @click="handleClick('Peter', $event)"
  >
    Button 1
  </button>
</template>

<script>
export default {
  methods: {
    handleClick(username, event) {
      const target = event.target;
      alert(
        `${username} clicked the button with ID ${target.id}`
      );
    },
  },
};
</script>

Vue Event Modifiers

Vue provides event modifiers that allow us to separate our data logic from event-related logic. For example, the .prevent event modifier eliminates the need to call event.preventDefault() in the event handler method:

<template>
  <form @submit.prevent="onSubmit">
    <input
      name="email"
      type="email"
      placeholder="Email"
    />
    <button type="submit">Sign up</button>
  </form>
</template>

<script>
export default {
  methods: {
    onSubmit() {
      alert('Signed up successfully.');
    },
  },
};
</script>

Similarly, the .stop event modifier removes the need to call event.stopPropagration() in an event method handler:

<template>
  <button
    id="outer-btn"
    @click="handleOuterButtonClick"
  >
    Outer button
    <button
      id="inner-btn"
      @click.stop="handleInnerButtonClick"
    >
      Inner button
    </button>
  </button>
  <p>{{ message1 }}</p>
  <p>{{ message2 }}</p>
</template>

<script>
export default {
  data() {
    return {
      message1: '',
      message2: '',
    };
  },
  methods: {
    handleOuterButtonClick() {
      this.message2 = 'Outer button clicked';
    },
    handleInnerButtonClick() {
      this.message1 = 'Inner button clicked.';
    },
  },
};
</script>
Handling an event in Vue with the .stop modifier.

Here is a list of the common event modifiers in Vue:

  • .stop
  • .prevent
  • .self
  • .capture
  • .once
  • .passive

Chained Event Modifiers

We can chain event modifiers in Vue:

<a @click.stop.prevent="handleLink1Click"></a>
  
<a @click.once.prevent="handleLink2Click"></a>

Key modifiers

It’s common to check for specific keys when listening for keyboard events. Vue provides key modifiers for this.

For example, we can listen just for the “Enter” key

<input @keyup.enter="handleSubmit" />

We can use any valid key names exposed through KeyboardEvent.key as modifiers by converting them to kebab-case:

<input @keyup.page-down="handlePageDown" />

Key Aliases

Vue provides aliases for the most frequently used keys:

  • .enter
  • .tab
  • .delete (captures both "Delete" and "Backspace" keys)
  • .esc
  • .space
  • .up
  • .down
  • .left
  • .right

System Modifier Keys

Applying system key modifiers to key events will only trigger the event when the corresponding modifier key is pressed.

<!-- Ctrl + Enter -->
<input @keyup.ctrl.enter="clearTextField" />

<!-- Ctrl + Click -->
<div @click.ctrl="handleCtrlClick">Do something</div>

Exact Modifier

The .exact modifier lets us control the exact combination of system modifiers needed to trigger an event:

<!-- this will fire even if Alt or Shift is also pressed -->
<button @click.ctrl="handleClick">Button</button>

<!-- this will only fire when Ctrl and no other keys are pressed -->
<button @click.ctrl.exact="handleCtrlClick">Button</button>

<!-- this will only fire when no system modifiers are pressed -->
<button @click.exact="handleClick">Button</button>

Mouse Button Modifiers

Mouse button event modifiers will only call the event handlers for specific buttons. They are:

  • .left
  • .middle
  • .right
<button @click.left="handleLeftClick">Button</button>

<button @click.middle="handleMiddleClick">Button</button>

<button @click.right="handleRightClick">Button</button>

Conclusion

We can listen for events in Vue by passing inline code or a method handler to the v-on directive for the event. We can apply various modifiers to an event to further customize event trigger conditions.



Every Crazy Thing JavaScript Does

A captivating guide to the subtle caveats and lesser-known parts of JavaScript.

Every Crazy Thing JavaScript Does

Sign up and receive a free copy immediately.

Leave a Comment

Your email address will not be published. Required fields are marked *