之前幫一個舊專案升版到 Vue3,整個就專案都是用 Bootstrap Vue 寫的,每個 input 都被包在 Bootstrap Vue 封裝好的元件裏面,為了把這些封裝好的 input 拆出來,我花了很多功夫。其中遇到的一個難題是 input 輸入框按 enter 會觸發表單重整,全部輸入框都被清空了,還會觸發 click 事件,執行不該執行的函式,而這不是我想要的結果。
我希望在 input 按 enter 的時候,不要觸發任何事件。
結果我發現它整個表單是用 <form></form>頭尾夾住,所以在 input 中按下enter,會觸發 submit 事件。
<script setup>
import { ref } from 'vue'
const msg = ref('Hello World!')
function alertMessage() {
alert('沒有prevent,表單輸入框會重置')
}
</script>
<template>
<h3>表單輸入</h3>
<form>
<div class="label-space">
<label for="name"> 姓名
<input id="name" type="text">
</label>
</div>
<div class="label-space">
<label for="age"> 年紀
<input id="age" type="number">
</label>
</div>
<button @click="alertMessage">其他輸入項</button>
</form>
</template>
<style scoped>
.label-space {
margin-bottom: 20px;
}
</style>
第一個嘗試的做法是在 input 上綁上 keydown 事件:@keydown.enter.prevent,然後綁上一個沒有內容的函式,但是我覺得這樣做有點奇怪。
<input id="name" type="text" @keydown.prevent="noop">
function noop(){
console.log('我只是為了input不要觸發form而存在')
}
<script setup>
import { ref } from 'vue'
const msg = ref('Hello World!')
function alertMessage() {
alert('沒有prevent,表單輸入框會重置')
}
function noop(){
console.log('我只是為了input不要觸發form而存在')
}
</script>
<template>
<h3>表單輸入</h3>
<form>
<div class="label-space">
<label for="name"> 姓名
<input id="name" type="text" @keydown.prevent="noop">
</label>
</div>
<div class="label-space">
<label for="age"> 年紀
<input id="age" type="number" @keydown.prevent="noop">
</label>
</div>
<button @click.prevent="alertMessage">其他輸入項</button>
</form>
</template>
<style scoped>
.label-space {
margin-bottom: 20px;
}
</style>
第二個做法是在 <button> 上加上 type=”button”,因為如果沒有設定 type,<button> type 預設為 submit,這樣如果表單內有 enter 的事件就會去觸發 submit,然後輸入框中的內容就被清空了。
但是如果設定 type=”button”,就不會觸發 submit,表單輸入框也不會重置了。
<script setup>
import { ref } from 'vue'
const msg = ref('Hello World!')
function alertMessage() {
alert('沒有prevent,表單輸入框會重置')
}
</script>
<template>
<h3>表單輸入</h3>
<form>
<div class="label-space">
<label for="name"> 姓名
<input id="name" type="text">
</label>
</div>
<div class="label-space">
<label for="age"> 年紀
<input id="age" type="number">
</label>
</div>
<button type="button" @click="alertMessage">其他輸入項</button>
</form>
</template>
<style scoped>
.label-space {
margin-bottom: 20px;
}
</style>
雖然前後端分離專案,比較少遇到要處理 <form> 的問題,但是遇到了也是措手不及,更何況這還是低級錯誤。
