2024-09-18|閱讀時間 ‧ 約 22 分鐘

EP10 - 表單輸入綁定

Form Input Bindings,綁定是指前後端串接起來了嗎?
看到綁定這種字眼,就想到前後端應該是數據保持同步更新了!
這樣是不是就省去很多處理資料需要同步的內容了~

處理前端表單時,我們常常需要同步表單輸入元素的狀態與 JavaScript 中的對應狀態。手動綁定值和變更事件監聽器可能會很麻煩:

<template>
<input
:value="text"
@input="event => text = event.target.value">
</template>

v-model 指令幫助我們簡化上述過程:

<template>
<input v-model="text">
</template>

此外,v-model 可以用於不同類型的輸入元素,包括 <textarea><select> 元素。根據所使用的元素,v-model 自動擴展到不同的 DOM 屬性和事件對:

  • <input> 元素的文本類型和 <textarea> 元素使用 value 屬性和 input 事件;
  • <input type="checkbox"><input type="radio"> 使用 checked 屬性和 change 事件;
  • <select> 使用 value 屬性和 change 事件。
注意v-model 會忽略在任何表單元素上發現的初始 valuecheckedselected 屬性。它總是將當前綁定的 JavaScript 狀態作為真實來源。你應該在 JavaScript 端使用響應式 API 宣告初始值。

基本用法 - Basic Usage

文字 - Text

<template>
<p>Message is: {{ message }}</p>
<input v-model="message" placeholder="edit me" />
</template>

Try it in the playground

注意:對於需要輸入法 (IME) 的語言(如中文、日文、韓文等),你會注意到在輸入法組成期間,v-model 不會更新。如果你想在這些更新時也能做出響應,請使用你自己的 input 事件監聽器和值綁定,而不是使用 v-model

多行文本 - Multiline text

<template>
<span>Multiline message is:</span>
<p style="white-space: pre-line;">{{ message }}</p>
<textarea v-model="message" placeholder="add multiple lines"></textarea>
</template>

Try it in the playground

注意:在 <textarea> 內插值不會生效。請使用 v-model
<template>
<!-- 錯誤 -->
<textarea>{{ text }}</textarea>

<!-- 正確 -->
<textarea v-model="text"></textarea>
</template>

核取方塊 - Checkbox

單個核取方塊,布林值:

<template>
<input type="checkbox" id="checkbox" v-model="checked" />
<label for="checkbox">{{ checked }}</label>
</template>

Try it in the playground

我們也可以將多個核取方塊綁定到同一個陣列或 Set 值:

const checkedNames = ref([])
<template>
<div>Checked names: {{ checkedNames }}</div>

<input type="checkbox" id="jack" value="Jack" v-model="checkedNames" />
<label for="jack">Jack</label>

<input type="checkbox" id="john" value="John" v-model="checkedNames" />
<label for="john">John</label>

<input type="checkbox" id="mike" value="Mike" v-model="checkedNames" />
<label for="mike">Mike</label>
</template>

在這種情況下,checkedNames 陣列將始終包含當前選中的核取方塊的值。

Try it in the playground

單選按鈕 - Radio

<template>
<div>Picked: {{ picked }}</div>

<input type="radio" id="one" value="One" v-model="picked" />
<label for="one">One</label>

<input type="radio" id="two" value="Two" v-model="picked" />
<label for="two">Two</label>
</template>

Try it in the playground

下拉選單 - Select

單選:

<template>
<div>Selected: {{ selected }}</div>

<select v-model="selected">
<option disabled value="">Please select one</option>
<option>A</option>
<option>B</option>
<option>C</option>
</select>
</template>

Try it in the playground

注意:如果 v-model 表達式的初始值不匹配任何選項,<select> 元素將呈現為“未選中”狀態。在 iOS 上,這將導致用戶無法選擇第一項,因為 iOS 在這種情況下不會觸發 change 事件。因此,建議提供一個帶有空值的禁用選項,如上例所示。

多選(綁定到陣列)- Multiple select (bound to array):

<template>
<div>Selected: {{ selected }}</div>

<select v-model="selected" multiple>
<option>A</option>
<option>B</option>
<option>C</option>
</select>
</template>

Try it in the playground

可以使用 v-for 動態渲染選項:

const selected = ref('A')

const options = ref([
{ text: 'One', value: 'A' },
{ text: 'Two', value: 'B' },
{ text: 'Three', value: 'C' }
])
<template>
<select v-model="selected">
<option v-for="option in options" :value="option.value">
{{ option.text }}
</option>
</select>

<div>Selected: {{ selected }}</div>
</template>

Try it in the playground

值綁定 - Value Bindings

對於單選按鈕、核取方塊和下拉選項,v-model 綁定的值通常是靜態字符串(或對於核取方塊是布林值):

`<template>
<!-- 當選中時,`picked` 是字符串 "a" -->
<input type="radio" v-model="picked" value="a" />

<!-- `toggle` 是 true 或 false -->
<input type="checkbox" v-model="toggle" />

<!-- 當選擇第一個選項時,`selected` 是字符串 "abc" -->
<select v-model="selected">
<option value="abc">ABC</option>
</select>
</template>

但有時我們可能希望將值綁定到當前活動實例上的動態屬性。我們可以使用 v-bind 來實現。此外,使用 v-bind 可以讓我們將輸入值綁定到非字符串值。

核取方塊 - Checkbox

<template>
<input
type="checkbox"
v-model="toggle"
true-value="yes"
false-value="no" />
</template>

true-valuefalse-value 是 Vue 特有的屬性,只適用於 v-model。在此範例中,當核取方塊被勾選時,toggle 屬性的值將被設置為 'yes',當未勾選時,則設置為 'no'。你也可以使用 v-bind 將它們綁定到動態值:

<template>
<input
type="checkbox"
v-model="toggle"
:true-value="dynamicTrueValue"
:false-value="dynamicFalseValue" />
</template>
提示:true-valuefalse-value 屬性不會影響輸入的 value 屬性,因為瀏覽器在表單提交時不包括未勾選的框。為了保證在表單中提交的值是其中之一(例如 "yes" 或 "no"),請改用單選按鈕。

單選按鈕 - Radio

<template>
<input type="radio" v-model="pick" :value="first" />
<input type="radio" v-model="pick" :value="second" />
</template>

當第一個單選按鈕被選中時,pick 將被設置為 first 的值;當第二個單選按鈕被選中時,pick 將被設置為 second 的值。

下拉選單選項 - Select Options

<template>
<select v-model="selected">
<!-- 內聯物件字面值 -->
<option :value="{ number: 123 }">123</option>
</select>
</template>

v-model 也支持非字串值的綁定!在上述範例中,當選項被選中時,selected 將被設置為物件字面值 { number: 123 }

Modifiers

.lazy

預設情況下,v-model 會在每個輸入事件後同步數據(IME 輸入法組合除外)。可以添加 lazy 修飾符來改為在更改事件後同步數據:

<template>
<!--"change" 事件後同步而非 "input" 事件 -->
<input v-model.lazy="msg" />
</template>

.number

如果希望用戶輸入自動轉換為數字類型,可以在 v-model 管理的輸入中添加 number 修飾符:

<template>
<input v-model.number="age" />
</template>

如果值無法通過 parseFloat() 解析,則使用原始的字串值。特別是,當輸入為空時(例如用戶清空輸入框後),將返回一個空字串。此行為與 DOM 屬性 valueAsNumber 不同。

如果輸入的 type 為 "number",則會自動應用 number 修飾符。

.trim

如果希望自動修剪用戶輸入中的空白字符,可以在 v-model 管理的輸入中添加 trim 修飾符:

<template>
<input v-model.trim="msg" />
</template>

v-model 與組件 - v-model with Components

如果你還不熟悉 Vue 的組件,可以暫時跳過這部分。

HTML 的內建輸入類型並不總是能滿足你的需求。幸運的是,Vue 組件允許你構建可重用的、具有完全自定義行為的輸入。這些輸入甚至可以與 v-model 一起使用!要了解更多,請閱讀組件指南中的 v-model 用法部分。

Q: v-bind 跟 v-model差異?

v-bind 指令主要用於綁定 HTML 屬性到 Vue 的數據。

<!-- 綁定 HTML 屬性 -->
<img v-bind:src="imageSrc" alt="Description">

<!-- 簡寫形式 -->
<img :src="imageSrc" alt="Description">

<!-- 綁定樣式 -->
<div :style="{ color: activeColor, fontSize: fontSize + 'px' }"></div>

<!-- 綁定類別 -->
<div :class="{ active: isActive }"></div>

v-model 指令主要用於實現雙向數據綁定,特別是在表單元素中使用。

<!-- 單行文字輸入 -->
<input v-model="message" placeholder="edit me">

<!-- 多行文字輸入 -->
<textarea v-model="message" placeholder="add multiple lines"></textarea>

<!-- 單選框 -->
<input type="checkbox" v-model="checked">

<!-- 單選按鈕 -->
<input type="radio" v-model="picked" value="option1">
<input type="radio" v-model="picked" value="option2">

<!-- 下拉選單 -->
<select v-model="selected">
<option disabled value="">Please select one</option>
<option>A</option>
<option>B</option>
<option>C</option>
</select>

差異總結

  • v-bind 用於綁定 HTML 屬性、樣式或類別到 Vue 數據的單向綁定指令。
  • v-model 用於實現表單元素與 Vue 數據雙向綁定指令,使表單輸入和數據同步更新。

這兩個指令在特定情況下可以互補使用,以實現更複雜的數據綁定需求。

使用 v-bind 綁定動態屬性

<template>
<div>
<!-- 靜態屬性綁定 -->
<input type="radio" v-model="picked" value="a">
<!-- 動態屬性綁定 -->
<input type="radio" v-model="picked" :value="dynamicValue">
</div>
</template>

<script>
export default {
data() {
return {
picked: null,
dynamicValue: 'b'
};
}
}
</script>

在上面的示例中,第一個單選按鈕有一個靜態的 value 屬性值 'a',而第二個單選按鈕的 value 屬性是動態的,通過 v-bind 綁定到實例的 dynamicValue 屬性。這樣,當 dynamicValue 的值改變時,單選按鈕的 value 也會相應更新。

綁定非字符串值

<template>
<div>
<!-- 綁定一個對象作為選擇值 -->
<select v-model="selected">
<option :value="{ number: 123 }">123</option>
<option :value="{ number: 456 }">456</option>
</select>

<!-- 綁定一個布爾值 -->
<input type="checkbox" v-model="toggle" :true-value="true" :false-value="false">
</div>
</template>

<script>
export default {
data() {
return {
selected: null,
toggle: false
};
}
}
</script>

在這個例子中:

  • 下拉選單中的選項綁定的是對象 { number: 123 }{ number: 456 },而不是簡單的字符串。當選中某個選項時,selected 將會設置為相應的對象。
  • 單選按鈕綁定的是布爾值 truefalse。當選中時,toggle 將會設置為 true,未選中時,toggle 會設置為 false

使用 v-bind 可以讓我們綁定複雜的數據類型,而不僅僅是字符串,這在處理更複雜的應用場景時非常有用。

講了一些東西,單獨分開講好像沒問題~
並在一起講開始有點模糊了~就像v-bind跟v-model
好像了解了!但其實好像沒這麼了解www ~
分享至
成為作者繼續創作的動力吧!
© 2024 vocus All rights reserved.