表单输入绑定
本教程共 40 篇 · 第 25 篇 · 更新于 2026-07-29 · 约 7 分钟阅读
25. 表单输入绑定
本节目标:掌握 v-model 在各类表单元素上的用法,理解其原理和修饰符。
v-model 的本质
表单元素和 JavaScript 状态之间的双向绑定,手动写很麻烦:
<input
:value="text"
@input="event => text = event.target.value"
>
v-model 把这坨简化成一个指令:
<input v-model="text">
根据使用的元素不同,v-model 会自动展开为不同的属性事件组合:
| 元素 | 属性 | 事件 |
|---|---|---|
| 文本 input / textarea | value | input |
| checkbox / radio | checked | change |
| select | value | change |
Notev-model 会忽略元素上初始的 value/checked/select 属性。初始值以 JavaScript 状态为准。
文本输入
<p>消息: {{ message }}</p>
<input v-model="message" placeholder="编辑我" />
<textarea> 同理。注意,<textarea> 内不能插值,必须用 v-model:
<!-- ❌ 错误 -->
<textarea>{{ text }}</textarea>
<!-- ✅ 正确 -->
<textarea v-model="text"></textarea>
复选框
单个 checkbox 绑定布尔值:
<input type="checkbox" id="checkbox" v-model="checked" />
<label for="checkbox">{{ checked }}</label>
多个 checkbox 绑定同一个数组:
<div>已选: {{ 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>
const checkedNames = ref([])
勾选谁,谁的 value 就进数组。取消勾选,自动移除。
自定义 true/false 值
默认 checkbox 绑定的是 true/false。用 true-value 和 false-value 自定义:
<input
type="checkbox"
v-model="toggle"
true-value="yes"
false-value="no"
/>
这些值也可以用 v-bind 绑定动态数据。
单选按钮
<div>选中: {{ 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>
单选按钮用 :value 绑定非字符串值也是可以的。
选择框
单选:
<div>选中: {{ selected }}</div>
<select v-model="selected">
<option disabled value="">请选择</option>
<option>A</option>
<option>B</option>
<option>C</option>
</select>
多选(绑定数组):
<select v-model="selected" multiple>
<option>A</option>
<option>B</option>
<option>C</option>
</select>
选项用 v-for 动态渲染:
<select v-model="selected">
<option v-for="option in options" :value="option.value">
{{ option.text }}
</option>
</select>
const options = ref([
{ text: '一', value: 'A' },
{ text: '二', value: 'B' },
{ text: '三', value: 'C' }
])
Tip如果初始值不匹配任何选项,select 会进入”未选中”状态。iOS 上这会导致无法选择第一项,所以建议加一个 disabled 的空值选项。
值绑定
v-model 绑定的值默认是字符串。如果想绑非字符串(比如对象),用 :value:
<!-- 选中时 selected = { number: 123 } -->
<select v-model="selected">
<option :value="{ number: 123 }">123</option>
</select>
单选按钮也一样:
<input type="radio" v-model="pick" :value="first" />
<input type="radio" v-model="pick" :value="second" />
修饰符
.lazy
默认在 input 事件后同步。.lazy 改成 change 事件后同步(失焦时):
<input v-model.lazy="msg" />
.number
自动把输入转成数字:
<input v-model.number="age" />
如果 parseFloat() 解析失败,就保留原始字符串。type="number" 会自动加这个修饰符。
.trim
自动去除首尾空格:
<input v-model.trim="msg" />
v-model 的实现原理
在原生元素上,v-model 本质是:
<!-- 文本 input -->
<input :value="text" @input="text = $event.target.value" />
<!-- checkbox -->
<input type="checkbox" :checked="checked" @change="checked = $event.target.checked" />
<!-- select -->
<select :value="selected" @change="selected = $event.target.value"></select>
在组件上,v-model 是 :modelValue + @update:modelValue 的语法糖。这就是上一节”组件 v-model”的基础。
本节回顾
- v-model 是
:value+@input的语法糖 - 不同类型的表单展开为不同属性事件组合
- checkbox 单用绑布尔,多用绑数组
- select 的选项支持 v-for 动态渲染
.lazy.number.trim三个修饰符处理常见场景- 组件上的 v-model 原理相通