Search code examples
vue.jseventsvuejs2

Pass event modifiers with v-on object syntax


According to vue we can pass events and handlers as objects (very useful for slots).

Script

computed: {
  on() {
    return {
      input: this.onInput,
      keyup: this.onEnter
    }
  }
}

Template

<template>
  <div>
    <slot name="mySlot" :on="on"></slot>
  </div>
<template>

So in this example, lets say the slot takes an input field. In this case, that input field will emit every input event and key up event. Both these events will be caught by the 'child component' which is the one defined here, that declares the slot.

However if we just wanted to get the 'enter' keyup event, this syntax doesn't seem to work.

Script

computed: {
  on() {
    return {
      input: this.onInput,
      'keyup.enter': this.onEnter
    }
  }
}

Using the above, the keyup enter event is not caught. Anyone know how to reconcile the syntax here, so the events can be caught?


Solution

  • The object syntax of v-on doesn't support event modifiers out of the box. The object keys can only be event names, so using keyup.enter would register an event listener for the nonexistent keyup.enter event (instead of the keyup event).

    One solution is to listen to keyup, and check the event's key for 'Enter':

    export default {
      computed: {
        on() {
          return {
            keyup: e => {
              if (e.key === 'Enter') {
                this.onEnter(e)
              }
            }
          }
        }
      }
    }
    

    demo