表单是 Web 应用中最常见的交互载体——登录、搜索、设置、问卷,几乎每个页面都离不开输入框、选择框和开关。Vue 提供 v-model 指令,让表单元素与响应式数据之间建立双向绑定:用户修改表单,数据自动更新;程序修改数据,表单也会随之变化。
v-model 双向绑定
v-model 的语法非常简洁:
<template>
<div>
<input v-model="text" placeholder="输入内容" />
<p>你输入的是:{{ text }}</p>
</div>
</template>
<script setup>
import { ref } from 'vue'
const text = ref('')
</script>
当用户在输入框中键入内容,text 的值同步变化;如果通过代码修改 text.value,输入框中的显示也会更新。这种“数据 <-> 视图”的双向通路,省去了手动监听 input 事件和修改 value 的步骤。
对不同表单元素,v-model 会自动绑定正确的属性和事件:
| 元素 | 绑定的属性 | 监听的事件 |
|------|-----------|-----------|
| <input type="text"> / <textarea> | value | input |
| <input type="checkbox"> | checked | change |
| <input type="radio"> | checked | change |
| <select> | value | change |
所以你可以用完全一致的方式处理各种表单控件:
<input type="checkbox" v-model="isChecked" />
<select v-model="selectedCity">
<option value="">请选择</option>
<option value="beijing">北京</option>
<option value="shanghai">上海</option>
</select>
对于单选框,v-model 会绑定到对应的 value 值;对于多选框,可以绑定到一个数组:
<input type="checkbox" v-model="hobbies" value="reading" /> 阅读
<input type="checkbox" v-model="hobbies" value="sports" /> 运动
<!-- 当选中时,hobbies 数组中会加入对应的 value -->
表单修饰符
v-model 还提供了三个实用的修饰符,直接在模板中处理常见需求,避免在逻辑代码中写冗余的清理或转换。
.lazy
默认情况下,v-model 在每次 input 事件触发时都会同步数据(即输入过程中实时更新)。加上 .lazy 后,它会改为在 change 事件触发时才同步,也就是当输入框失去焦点或用户按回车时才更新数据。
<input v-model.lazy="text" placeholder="失焦时才更新" />
<p>{{ text }}</p>
适用场景:搜索框不必在用户每敲一个字就触发搜索,而是输完一段完整内容后再触发,减少不必要的请求。
.number<input type="number"> 的值在 JavaScript 中默认是字符串,v-model.number 会自动将输入转换为数值类型。如果转换失败(如用户输入 “abc”),则保持原值。
<input v-model.number="age" type="number" />
<p>年龄加10:{{ age + 10 }}</p>
如果没有 .number,age + 10 会变成字符串拼接(如 "25" + 10 = "2510");使用修饰符后就能得到正确的数字运算。
.trim
自动过滤用户输入首尾的空白字符,适用于用户名、邮箱等场景。
<input v-model.trim="username" placeholder="用户名" />
<p>["{{ username }}"]</p>
<!-- 输入 " alice " 会变成 "alice" -->
这些修饰符可以链式使用,比如 v-model.lazy.trim="keyword" 表示失焦时更新且去除首尾空格。
注意事项
v-model本质是:value+@input的语法糖(不同表单元素具体绑定的属性有差异)。如果需要更精细的控制,可以拆开手动实现。- 在 组合式 API 中,
v-model绑定的变量必须是响应式数据(ref或reactive),这样可以保证双向响应的链条不断裂。 - 对于自定义组件,也可以通过
v-model实现双向绑定,原理是利用modelValue属性和update:modelValue事件(详见第9章)。
掌握 v-model 和这三个修饰符,日常表单开发中绝大部分的输入同步需求都能得到干净利落的解决。