← Other topics

Vue.js Simplified - Event Handling (#6)

Series contents:

Video Notes

The v-on directive can be used to listen for DOM events such as click, change, mouseover, mouseout, keyup, etc.

Events are specified as an argument of the v-on directive, e.g. v-on:click:

<button v-on:click="correct = wordB == answer">Check answer</button>

The syntax for specifying arguments for a directive is always: v-directive:argument

Inline handlers

One type of value you can specify for v-on is an inline JavaScript expression. For example, in the above code, the expression is correct = wordB == answer.

Multiple expressions can be separated by a semi-colon, for example:

<button v-on:click='correct = wordB == answer; showFeedback = true'>Check answer</button>

Method handlers

When the task at hand calls for multiple statements, it makes sense to move the statements to their own function which can then be invoked from the event listener.

Such functions can be defined in a methods option in your Vue options:

const FlashWord = {
    data() {
        return {
            wordA: 'hola',
            wordB: 'hello',
            answer: '',
            correct: null,
            showFeedback: false,
        }
    },
    methods: {
        checkAnswer() {
            // The keyword `this` is used to access properties from our data option
            this.correct = this.wordB == this.answer;
            this.showFeedback = true;
        }
    }
}

Our new checkAnswer function can now be invoked from the v-on:click:

<button v-on:click='checkAnswer()'>Check answer</button>

Observations:

  • When we’re referencing our data options from within our methods, we had to use the this keyword (e.g. this.correct = this.wordB == this.answer;). This step was not necessary when accessing these same options within our template.
  • While not necessary in the above example, methods can be defined with parameters and accept arguments.

So far, we’ve studied two Vue options: data and methods. Later, we’ll add additional options, and it can be useful to be consistent in the order in which we set these options.

Refer to the Vue style guide’s suggestions on options order for guidance on this.

Event argument

Details about the DOM event can be accessed like so:

<button v-on:click='checkAnswer($event)'>Check answer</button>
const FlashWord = {
    // [...data options redacted for brevity...]
    methods: {
        checkAnswer(event) {

            // Demonstrating accessing info about the DOM event
            console.log(event);
            
            this.correct = this.wordB == this.answer;
            this.showFeedback = true;
        }
    }
}

Modifiers

Some directives, including v-on, can also accept modifiers following this syntax:

v-directive:argument.modifier

For example, the keyup event listener can accept a key modifier to indicate which specific key (e.g. enter, shift, tab) it should listen for.

Using this technique, we could make it possible to submit an answer by hitting the enter key right after the user types in their guess:

<input type='text' v-model='answer' v-on:keyup.enter='checkAnswer()'>

<button v-on:click='checkAnswer()'>Check answer</button>

Vue supports all the standard JS keyboard events, you just need to specify them in lower-kebab-case.

Examples:

  • CapsLock is caps-lock
  • Shift is shift
  • PageDown is page-down
  • Etc.

v-on shorthand syntax @

The v-on directive is one of those directives you’ll use frequently, so a syntax shorthand exists to abbreviate it. Instead of writing v-on, you can use the @ symbol.

Example:

<input type='text' v-model='answer' v-on:keyup.enter='checkAnswer()'>

<button @click='checkAnswer()'>Check answer</button>

Either style is acceptable in your projects, but per the Vue style guide, it’s suggested that you are consistent with your usage of shorthands.

A shift in convention

The v-on directive looks very similar to how one might trigger a JavaScript method using plain JavaScript and a DOM on-event handler.

Example:

<button onclick='checkAnswer()'>Check answer</button>

When learning to write front-end JavaScript, we’re often taught this is bad because it breaks separation of concerns by mixing JavaScript (interactivity) into our HTML (display).

Instead, we were taught to set up an event listener in our JavaScript— something like this:

document.querySelector('button').addEventListener('click', checkAnswer);

The perspective on this has changed, though, in frameworks such as Vue, where we want the JavaScript to be declarative and data-driven, with a de-emphasis on direct interaction with the DOM.

If this info helped you out you can say thanks and support future content by clicking my Amazon affiliate link: https://amzn.to/3UtgnYk. If you make a purchase on Amazon within 24 hours of clicking the link I may receive a micro-commission and it costs you nothing extra. Any income from these sales goes directly to supporting me in making new videos and guides. Thank you for your support!

← Other topics