[javascript] Handling Enter Key in Vue.js

I'm learning Vue.js. In my Vue, I have a text field and a button. By default, this button submits a form when someone presses the Enter key on their keyboard. When someone is typing in the text field, I want to capture each key pressed. If the key is an '@' symbol, I want to do something special. If the key pressed is the "Enter" key, I want to do something special as well. The latter is the one giving me challenges. Currently, I have this Fiddle, which includes this code:

new Vue({
  el: '#myApp',
  data: {
    emailAddress: '',
    log: ''
  },
  methods: {
    validateEmailAddress: function(e) {
      if (e.keyCode === 13) {
        alert('Enter was pressed');
      } else if (e.keyCode === 50) {
        alert('@ was pressed');
      }      
      this.log += e.key;
    },

    postEmailAddress: function() {
      this.log += '\n\nPosting';
    }
});

In my example, I can't seem to press the "Enter" key without it submitting the form. Yet, I would expect the validateEmailAddress function to at least fire first so that I could capture it. But, that does not seem to be happening. What am I doing wrong?

This question is related to javascript vue.js

The answer is


Event Modifiers

You can refer to event modifiers in vuejs to prevent form submission on enter key.

It is a very common need to call event.preventDefault() or event.stopPropagation() inside event handlers.

Although we can do this easily inside methods, it would be better if the methods can be purely about data logic rather than having to deal with DOM event details.

To address this problem, Vue provides event modifiers for v-on. Recall that modifiers are directive postfixes denoted by a dot.

<form v-on:submit.prevent="<method>">
  ...
</form>

As the documentation states, this is syntactical sugar for e.preventDefault() and will stop the unwanted form submission on press of enter key.

Here is a working fiddle.

_x000D_
_x000D_
new Vue({_x000D_
  el: '#myApp',_x000D_
  data: {_x000D_
    emailAddress: '',_x000D_
    log: ''_x000D_
  },_x000D_
  methods: {_x000D_
    validateEmailAddress: function(e) {_x000D_
      if (e.keyCode === 13) {_x000D_
        alert('Enter was pressed');_x000D_
      } else if (e.keyCode === 50) {_x000D_
        alert('@ was pressed');_x000D_
      }      _x000D_
      this.log += e.key;_x000D_
    },_x000D_
    _x000D_
    postEmailAddress: function() {_x000D_
   this.log += '\n\nPosting';_x000D_
    },_x000D_
    noop () {_x000D_
      // do nothing ?_x000D_
    }_x000D_
  }_x000D_
})
_x000D_
html, body, #editor {_x000D_
  margin: 0;_x000D_
  height: 100%;_x000D_
  color: #333;_x000D_
}
_x000D_
<script src="https://unpkg.com/[email protected]/dist/vue.js"></script>_x000D_
<div id="myApp" style="padding:2rem; background-color:#fff;">_x000D_
<form v-on:submit.prevent="noop">_x000D_
  <input type="text" v-model="emailAddress" v-on:keyup="validateEmailAddress" />_x000D_
  <button type="button" v-on:click="postEmailAddress" >Subscribe</button> _x000D_
  <br /><br />_x000D_
  _x000D_
  <textarea v-model="log" rows="4"></textarea>  _x000D_
</form>_x000D_
</div>
_x000D_
_x000D_
_x000D_


You can also pass events down into child components with something like this:

<CustomComponent
    @keyup.enter="handleKeyUp"
/>

...

<template>
    <div>
        <input
            type="text"
            v-on="$listeners"
        >
    </div>
</template>

<script>
export default {
    name: 'CustomComponent',

    mounted() {
        console.log('listeners', this.$listeners)
    },
}
</script>

That works well if you have a pass-through component and want the listeners to go onto a specific element.


In vue 2, You can catch enter event with v-on:keyup.enter check the documentation:

https://vuejs.org/v2/guide/events.html#Key-Modifiers

I leave a very simple example:

_x000D_
_x000D_
var vm = new Vue({_x000D_
  el: '#app',_x000D_
  data: {msg: ''},_x000D_
  methods: {_x000D_
    onEnter: function() {_x000D_
       this.msg = 'on enter event';_x000D_
    }_x000D_
  }_x000D_
});
_x000D_
<script src="https://cdn.jsdelivr.net/npm/vue"></script>_x000D_
_x000D_
<div id="app">_x000D_
  <input v-on:keyup.enter="onEnter" />_x000D_
  <h1>{{ msg }}</h1>_x000D_
</div>
_x000D_
_x000D_
_x000D_

Good luck


You forget a '}' before the last line (to close the "methods {...").

This code works :

_x000D_
_x000D_
Vue.config.keyCodes.atsign = 50;_x000D_
_x000D_
new Vue({_x000D_
  el: '#myApp',_x000D_
  data: {_x000D_
    emailAddress: '',_x000D_
    log: ''_x000D_
  },_x000D_
  methods: {_x000D_
  _x000D_
    onEnterClick: function() {_x000D_
     alert('Enter was pressed');_x000D_
    },_x000D_
    _x000D_
    onAtSignClick: function() {_x000D_
     alert('@ was pressed');_x000D_
    },_x000D_
    _x000D_
    postEmailAddress: function() {_x000D_
   this.log += '\n\nPosting';_x000D_
    }_x000D_
  }_x000D_
})
_x000D_
html, body, #editor {_x000D_
  margin: 0;_x000D_
  height: 100%;_x000D_
  color: #333;_x000D_
}
_x000D_
<script src="https://vuejs.org/js/vue.min.js"></script>_x000D_
_x000D_
<div id="myApp" style="padding:2rem; background-color:#fff;">_x000D_
_x000D_
  <input type="text" v-model="emailAddress" v-on:keyup.enter="onEnterClick" v-on:keyup.atsign="onAtSignClick" />_x000D_
  _x000D_
  <button type="button" v-on:click="postEmailAddress" >Subscribe</button> _x000D_
  <br /><br />_x000D_
  _x000D_
  <textarea v-model="log" rows="4"></textarea>_x000D_
</div>
_x000D_
_x000D_
_x000D_


This event works to me:

@keyup.enter.native="onEnter".

For enter event handling you can use

  1. @keyup.enter or
  2. @keyup.13

13 is the keycode of enter. For @ key event, the keycode is 50. So you can use @keyup.50.

For example:

<input @keyup.50="atPress()" />