iT邦幫忙

2024 iThome 鐵人賽

DAY 13
1
Modern Web

Vue 3 初學者:用實作帶你看過核心概念系列 第 13

Vue 3 用實作帶你看過核心概念 - Day 13:v-model 雙向綁定控制 - 常用於表單輸入

  • 分享至 

  • xImage
  •  

文章背景圖

目錄

  • 表單輸入語法糖 - v-model
  • v-model 純文字輸入 - input type="text" & textarea
  • v-model 單個核取方塊(checkbox) & 單選按鈕(radio)
  • v-model 單選下拉式選單
  • v-model 多選下拉式選單 & 多選核取方塊
  • v-model 修飾符 - 減少使用者處理 DOM 事件細節
  • 總結

表單輸入語法糖 - v-model

表單輸入是開發中非常常見的需求,原始方式通常需要手動使用v-bind綁定表單元素的值 (value),並透過v-on綁定input事件來監聽輸入變化。

然而,當使用v-model進行雙向綁定時,表單元素的初始的valuecheckedselected屬性值會被忽略,取而代之的是由v-model綁定的數據來控制這些值。

👉 Vue3 Options API - v-model 原理解析 & 拼字階段差異實作連結

Vue Template(未使用 v-model):

<input :value="originValue" @input="onInputChange" type="text">

Vue Template(使用 v-model):

<input v-model="originValue" type="text">

⭐ 特別注意:若需要看到拼字階段(EX:中文注音)的改變,需要使用原始@input搭配:value的方式。v-model改動的是拼字結束後的結果。對應到原生javaScriptcompositionstartcompositionend 事件,捕捉拼字階段的開始及結束。

v-model 純文字輸入 - input type="text" & textarea

v-model綁定的情況下,不論是單行輸入的input還是多行輸入的textarea,綁定的都是字串(String)類型的數據。它們的差異比較如下:

  • input type="text" 支持單行輸入:僅限於單行輸入,不支持顯示換行符,即使輸入了換行符號,輸入框也不會顯示。
  • textarea 支持多行輸入:用戶在輸入時,按下 Enter 鍵會插入換行符號(\n),並在顯示時保留這些換行符號。

textArea 相較 input v-model 綁定可以看到換行符號

👉 Vue3 Options API input 單行輸入及 textarea 多行輸入實作連結

Vue Template:

<input v-model="msg" type="text">
<textarea v-model="msg" cols="15" rows="5"></textarea>
<p>顯示 v-model 的值: {{ JSON.stringify(msg) }}</p>
<p>顯示 v-model 長度: {{ msg.length }}</p>

v-model 單個核取方塊(checkbox) & 單選按鈕(radio)

當使用v-model綁定核取方塊或單選按鈕時,默認情況下,核取方塊綁定的是布林值(truefalse)。不過,核取方塊可以通過true-valuefalse-value屬性來改變其綁定的自定義值(EX:字串、數字)。單選按鈕則綁定的是其選定的值(EX:字串、數字)。它們的差異如下:

  • 單個核取方塊:當核取方塊被選中時,其值才會包含在表單提交中;若未選中,則不會提交任何數據。可以通過true-valuefalse-value屬性來自定義選中和未選中的值
  • 單選按鈕:每個單選按鈕都必須具備一個選定的值。即使在表單提交時,只有一個單選按鈕被選中,也能確保表單提交包含該選定值。

v-model 搭配核取方塊無法保證有值

⭐ 如果需要確保表單提交時一定有選取結果,建議使用單選按鈕作為選擇方式。
👉 原生表單單選按鈕跟單個核取方塊的差別實做連結

以下展示關於 Vue v-model 指令搭配單個核取方塊及單選按鈕的用法:
單選按鈕和單個核取方塊範例展示圖

👉 Vue Options API 單選按鈕及單個核取方塊實作連結

Radio Button Vue Template:

<label for="male">男生</label>
<input v-model="gender" id="male" name="gender" type="radio" value="男生">
<label for="feMale">女生</label>
<input v-model="gender" id="feMale" name="gender" type="radio" value="女生">
<p>當前性別:{{ gender }}</p>

Checkbox Button Vue Template(預設寫法):

<label for="isAgree">【 請問你是否同意此條款 】</label>
<input v-model="isAgree" id="isAgree" type="checkbox">
<p>同意與否: {{ isAgree }}</p>

Checkbox Button Template(使用true-valuefalse-value):

<label for="isAgreeString">【 請問你是否同意此條款 】</label>
<input v-model="isAgreeString" true-value="是" false-value="否" id="isAgreeString" type="checkbox">
<p>同意與否: {{ isAgreeString }}</p>

v-model 單選下拉式選單

使用 v-model 綁定單選下拉式選單時,可以透過設置一個帶有disabled屬性的空值選項,來顯示預設提示文字(EX:請選擇)。當使用者選擇其他選項後,該提示文字將不再顯示。

v-model綁定的情況下,選擇的值會對應到選項 (option) 中定義的value屬性。這個值可以是字串、數字。

單選下拉式選單示意圖

👉 Vue3 Options API 單選下拉式選單實作連結

HTML:

<label for="fruit-select">今天特賣會水果:</label>
<select v-model="selectValue" name="fruit" id="fruit-selec">
<option disabled value="">請選擇</option>
<option v-for="item in selectOptions" :value="item" :key="item">{{ item }}</option>
</select>

v-model 多選下拉式選單 & 多選核取方塊

多選下拉式選單與單選下拉式選單的區別在於是否使用了multiple屬性。

使用v-model綁定多選下拉式選單和多選核取方塊時,所綁定的值必須是以陣列(Array的形式呈現,以存儲多個選項的結果。

⭐ 多選下拉式選單與多選核取方塊之間有一個重要的差異:在多選下拉式選單中,v-model綁定的陣列元素順序會依據選項在原始陣列中的順序。而在多選核取方塊中v-model綁定的陣列元素則會按照選取的順序排列。

多選下拉式選單跟多選核取方塊差異圖

👉 Vue Options API 多選下拉式選單及多選核取方塊實作連結

多選下拉式選單 Vue Template:

<label for="skill">選擇你的技能:</label>
<select v-model="selectSkill" multiple name="skill-select" id="skill">
<option v-for="item in options" :key="item" :value="item">{{ item }}</option>
</select>
<p>當前多選下拉式選單:{{ selectSkill }}</p>

多選核取方塊 Vue Template:

<template v-for="item in options">
<label :for="`skill-${item}`">{{ item }}</label>
<input v-model="checkedSkill" type="checkbox" name="skill-checkbox" :id="`skill-${item}`" :value="item">
</template>
<p>當前多選核取方塊:{{ checkedSkill }}</p>

v-model 修飾符 - 減少使用者處理 DOM 事件細節

前面提到過v-on 指令可以搭配修飾符,這裡將說明v-model 指令所對應的修飾符

  1. lazy 修飾符
    原本的v-model會在每次輸入時通過input 事件立即更新綁定的數據,而使用.lazy 修飾符後,數據更新將改為依賴change 事件。這代表只有當使用者完成輸入並移開鼠標或按下 Enter 鍵後,綁定的v-model 值才會更新。這樣可以減少即時偵測的頻率,適合不需要每次輸入都同步更新的場景。

👉 Vue3 Options API v-model lazy 修飾符實作連結

HTML:

<input v-model.lazy="lazyInputValue" id="lazyMsg" type="text">
  1. number 修飾符
    輸入的值會被 JavaScript 的parseFloat()函數處理,嘗試將其轉換為數字類型。根據輸入的值,有以下兩種解析結果:
  • 輸入解析為NaN:如果輸入的值完全不包含數字,例如 abc,v-model.number不會轉換它,會顯示為原始字串的值及型別(EX:String)。
  • 輸入包含數字:當輸入值包含數字和非數字字符時,v-model.number會僅解析出數字部分,例如輸入 100abc,結果會顯示為 100。

使用 number 修飾符與未使用型別判定處理

👉 Vue3 Options API v-model number 修飾符實作連結

HTML:

<input v-model.number="numberInputValue" type="text" id="textInput">
  1. trim 修飾符
    trim 修飾符會自動去除輸入內容中的頭尾空白,這在輸入電子郵件或密碼等情境中非常常用,能有效避免由多餘空白導致的輸入錯誤。

使用 trim 修飾符輸入空白長度差別圖

👉 Vue3 Options API v-model trim 修飾符實作連結

HTML:

<input v-model.trim="useTrimValue" type="text" id="textInput">

總結

  • v-model 語法糖:本質上是通過@input事件來監聽輸入變化,並使用:value將輸入的值綁定回輸入框,從而實現雙向數據綁定。
  • v-model 多種綁定值類型
    • 單行輸入框 (input)多行輸入框 (textarea) 綁定的是字串 (String)
    • 多選下拉式選單(select)多選核取方塊(checkbox)綁定的是陣列 (Array)
    • 單選核取方塊 (checkbox) 預設綁定布林值 (Boolean)
    • 單選核取方塊使用true-valuefalse-value屬性、單選按鈕 (radio button)以及單選下拉式選單則可以綁定多種數據類型(如字串、數字、物件等)。
  • v-model 修飾符
    • lazy:將偵測事件從input切換為change,只有在按下 Enter 鍵或移開鼠標時才會更新值,從而減少觸發頻率。
    • number:將輸入的內容轉換為數字類型。若轉換結果為NaN,則會顯示原始值及其類型(如字串)。
    • trim:自動去除輸入內容的前後空白字符,避免因多餘空白字符導致輸入錯誤。

上一篇
Vue 3 用實作帶你看過核心概念 - Day 12:v-on 指令 - 事件處理
下一篇
Vue 3 用實作帶你看過核心概念 - Day 14:生命週期鉤子(Lifecycle Hooks)
系列文
Vue 3 初學者:用實作帶你看過核心概念30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言