Vue3-在 input 輸入框按 enter 觸發form刷新解法

之前幫一個舊專案升版到 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> 的問題,但是遇到了也是措手不及,更何況這還是低級錯誤。

Leave a Reply

Your email address will not be published. Required fields are marked *