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()ellerevent.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
@keyup.entereller@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" />
