javascript - Håndtere Enter-tasten i Vue.js


Jeg har et tekstfelt og en knapp.
Som standard sender denne knappen inn et skjema når noen trykker på Enter-tasten på tastaturet.
Når noen skriver i tekstfeltet, ønsker jeg å fange opp hver tast som trykkes. Hvis tasten er et @-symbol, ønsker jeg å gjøre noe spesielt.

Hvis tasten som trykkes er Enter-tasten, vil jeg også gjøre noe spesielt. Det siste er det som gir meg utfordringer. For øyeblikket har jeg denne Fiddle, som inkluderer denne koden:

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';
    }
});

I mitt eksempel ser det ut til at jeg ikke kan trykke på Enter-tasten uten at det sender inn skjemaet. Likevel ville jeg forventet at validateEmailAddress-funksjonen i det minste skulle kjøre først slik at jeg kunne fange det opp. Men det ser ikke ut til å skje.
Hva gjør jeg feil?

Svar #1

I Vue 2 kan du fange enter-hendelsen med v-on:keyup.enter, sjekk dokumentasjonen:

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

Jeg gir et veldig enkelt eksempel:

var vm = new Vue({
  el: '#app',
  data: {msg: ''},
  methods: {
    onEnter: function() {
       this.msg = 'on enter event';
    }
  }
});
<script src="https://cdn.jsdelivr.net/npm/[email /dist/vue.js"></script>

<div id="app">
  <input v-on:keyup.enter="onEnter" />
  <h1>{{ msg }}</h1>
</div>

Svar #2

Hendelsesmodifikatorer

Du kan referere til hendelsesmodifikatorer i Vue.js for å forhindre skjemainnsending ved enter-tasten.

Det er et veldig vanlig behov å kalle event.preventDefault() eller event.stopPropagation() inne i hendelseshåndterere.

Selv om vi kan gjøre dette enkelt inne i metoder, ville det være bedre om metodene kunne handle rent om datalogikk i stedet for å måtte håndtere detaljer om DOM-hendelser.

For å løse dette problemet tilbyr Vue hendelsesmodifikatorer for v-on. Husk at modifikatorer er direktivefterstillelser som angis med et punktum.

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

Som dokumentasjonen sier, er dette syntaktisk sukker for e.preventDefault() og vil stoppe den uønskede innsendingen av skjemaet ved trykk på enter-tasten.

Her er en fungerende prøve.

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';
    },
    noop () {
      // do nothing ?
    }
  }
})
html, body, #editor {
  margin: 0;
  height: 100%;
  color: #333;
}
<script src="https://unpkg.com/[email /dist/vue.js"></script>
<div id="myApp" style="padding:2rem; background-color:#fff;">
<form v-on:submit.prevent="noop">
  <input type="text" v-model="emailAddress" v-on:keyup="validateEmailAddress" />
  <button type="button" v-on:click="postEmailAddress" >Subscribe</button> 
  <br /><br />
  
  <textarea v-model="log" rows="4"></textarea>  
</form>
</div>

Svar #3

For håndtering av enter-hendelser kan du bruke

  1. @keyup.enter eller
  2. @keyup.13

13 er keycode for enter. For @ tastetrykk, er keycode 50. Så du kan bruke @keyup.50.

For eksempel:

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

Svar #4

Denne hendelsen fungerer for meg:

@keyup.enter.native="onEnter".

Svar #5

Du glemmer en '}' før siste linje (for å lukke 'methods {...').

Denne koden fungerer:

Vue.config.keyCodes.atsign = 50;

new Vue({
  el: '#myApp',
  data: {
    emailAddress: '',
    log: ''
  },
  methods: {
  
    onEnterClick: function() {
    	alert('Enter was pressed');
    },
    
    onAtSignClick: function() {
    	alert('@ was pressed');
    },
    
    postEmailAddress: function() {
			this.log += '\n\nPosting';
    }
  }
})
html, body, #editor {
  margin: 0;
  height: 100%;
  color: #333;
}
<script src="https://vuejs.org/js/vue.min.js"></script>

<div id="myApp" style="padding:2rem; background-color:#fff;">

  <input type="text" v-model="emailAddress" v-on:keyup.enter="onEnterClick" v-on:keyup.atsign="onAtSignClick" />
  
  <button type="button" v-on:click="postEmailAddress" >Subscribe</button> 
  <br /><br />
  
  <textarea v-model="log" rows="4"></textarea>
</div>

Svar #6

Du kan også sende hendelser videre til underordnede komponenter med noe som dette:

<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>

Det fungerer godt hvis du har en pass-through-komponent og ønsker at lytterne skal gå videre til et spesifikt element.

Svar #7

Vue 3

I Vue 3 fungerer denne koden hvis du vil lytte til enter-hendelsen på input:

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

Eller kanskje du vil at hendelsen din skal utløses når tasten trykkes ned, i stedet for når den slippes:

<input @keydown.enter="onPressEnter" />

Relaterte artikler