v-model
?是 Vue 中最強大的指令之一,它簡化了表單數據雙向綁定的實現。本文將系統梳理各種 HTML 表單元素與?v-model
?的綁定關系,特別是那些容易引起困惑的類型。
一、v-model
?的本質
v-model
?是一個語法糖,它實際上是?:value
?和?@input
?的組合(對于大多數元素)。在 Vue 3 中,這個機制變得更加靈活和強大。
<!-- 等價關系 -->
<input v-model="text">
<!-- 等同于 -->
<input :value="text" @input="text = $event.target.value">
二、文本輸入類元素
1. 普通文本輸入 (type="text"
)
綁定值:value
?屬性
觸發事件:input
?事件
<input type="text" v-model="message">
<!-- 等價于 -->
<input type="text" :value="message" @input="message = $event.target.value"
>
2. 多行文本 (textarea
)
綁定值:value
?屬性
觸發事件:input
?事件
<textarea v-model="content"></textarea>
注意:<textarea>{{ content }}</textarea>
?這種插值語法不會生效。
三、選擇類元素
1. 單選框 (type="radio"
)
這是最容易引起困惑的表單元素之一。
綁定值:checked
?狀態
觸發事件:change
?事件
特殊機制:通過比較?v-model
?綁定的值和?value
?屬性來決定是否選中
<input type="radio" value="yes" v-model="answer"> 是
<input type="radio" value="no" v-model="answer"> 否
等效于:?
<input type="radio" value="yes" :checked="answer==='yes'" @change="answer='yes'"> 是
<input type="radio" value="no" :checked="answer==='no'" @change="answer='no'"> 否
?
關鍵點:
同一組的 radio 必須綁定相同的?
v-model
v-model
?綁定的值會與每個 radio 的?value
?進行比較匹配時自動設置?
checked
?屬性用戶選擇時會將該 radio 的?
value
?賦給綁定的變量
類型轉換:
默認將?
value
?視為字符串如果需要其他類型,使用?
:value
?綁定:<input type="radio" :value="true" v-model="isAgree"> 同意
2. 復選框 (type="checkbox"
)
分為單個和多個兩種情況。
單個復選框:
綁定值:checked
?狀態
觸發事件:change
?事件
綁定類型:布爾值
<input type="checkbox" v-model="isChecked">
<!-- 等價于 -->
<input type="checkbox" :checked="isChecked" @change="isChecked = $event.target.checked"
>
多個復選框(數組綁定):
綁定值:checked
?狀態
觸發事件:change
?事件
綁定類型:數組
<input type="checkbox" value="vue" v-model="skills"> Vue
<input type="checkbox" value="react" v-model="skills"> React
選中時,value
?會被添加到數組中,取消選中時移除。
3. 下拉選擇框 (select
)
單選:
綁定值:選中的?option
?的?value
觸發事件:change
?事件
<select v-model="selectedCity"><option value="bj">北京</option><option value="sh">上海</option>
</select>
多選(添加?multiple
?屬性):
綁定值:所有選中?option
?的?value
?數組
觸發事件:change
?事件
<select v-model="selectedCities" multiple><option value="bj">北京</option><option value="sh">上海</option>
</select>
四、特殊輸入類型
1. 數字輸入 (type="number"
)
綁定值:valueAsNumber
?或?value
觸發事件:input
?事件
類型轉換:自動轉換為 Number 類型
<input type="number" v-model="age">
2. 范圍滑塊 (type="range"
)
綁定值:value
?屬性
觸發事件:input
?事件
<input type="range" v-model="volume" min="0" max="100">
3. 日期時間輸入 (type="date"
,?type="time"
?等)
綁定值:value
?屬性(格式化為字符串)
觸發事件:input
?事件
<input type="date" v-model="birthday">
五、自定義組件的?v-model
在 Vue 3 中,自定義組件的?v-model
?行為有了重大變化:
<CustomInput v-model="searchText" />
<!-- 等價于 -->
<CustomInput :modelValue="searchText"@update:modelValue="newValue => searchText = newValue"
/>
可以在組件中通過?defineProps
?和?defineEmits
?來處理:
// 子組件
const props = defineProps(['modelValue'])
const emit = defineEmits(['update:modelValue'])
六、最佳實踐與常見問題
類型一致性:確保?
v-model
?綁定的變量類型與?value
?類型匹配性能考慮:對于大型表單,考慮使用?
lazy
?修飾符減少更新頻率<input v-model.lazy="message">
修飾符:
.number
:自動將輸入轉為數字.trim
:自動去除首尾空格
七、總結對比表
元素類型 | 綁定屬性 | 觸發事件 | 綁定值類型 | 特殊說明 |
---|---|---|---|---|
text, textarea | value | input | string | - |
radio | checked | change | any | 比較?value ?和綁定值 |
checkbox (單個) | checked | change | boolean | - |
checkbox (多個) | checked | change | array | 收集所有選中的?value |
select (單選) | value | change | any | 匹配?option ?的?value |
select (多選) | value | change | array | 收集所有選中的?value |
number | valueAsNumber | input | number | 自動類型轉換 |
range | value | input | number/string | - |
date/time | value | input | string | 使用標準格式 (YYYY-MM-DD) |
理解這些綁定差異將幫助您更高效地使用 Vue 處理表單邏輯,避免常見的陷阱。特別是在處理 radio 和 checkbox 時,明確綁定機制可以節省大量調試時間。