在Vue.js项目开发中,表单是用户与页面交互的重要载体,v-model指令可以帮我们轻松实现表单输入和应用状态之间的双向绑定,不需要手动监听输入事件再更新数据。下面我们就详细讲解不同表单元素下v-model的使用方法。

基础文本输入框绑定
对于普通的文本输入框,包括单行输入框<input type="text">和多行文本域<textarea>,v-model会直接绑定输入框的value值,输入内容变化时对应的数据会自动更新。
<template>
<div>
<!-- 单行文本输入框 -->
<label>用户名:</label>
<input type="text" v-model="username" placeholder="请输入用户名">
<p>当前输入的用户名:{{ username }}</p>
<!-- 多行文本域 -->
<label>个人简介:</label>
<textarea v-model="intro" placeholder="请输入个人简介"></textarea>
<p>当前输入的简介:{{ intro }}</p>
</div>
</template>
<script>
export default {
data() {
return {
username: '',
intro: ''
}
}
}
</script>单选框绑定
单选框通常成组出现,需要给同一组的单选框设置相同的name属性,v-model绑定同一个数据,选中的单选框的value值会赋值给绑定的数据。
<template>
<div>
<label>性别:</label>
<input type="radio" id="male" value="男" v-model="gender">
<label for="male">男</label>
<input type="radio" id="female" value="女" v-model="gender">
<label for="female">女</label>
<p>当前选择的性别:{{ gender }}</p>
</div>
</template>
<script>
export default {
data() {
return {
gender: ''
}
}
}
</script>多选框绑定
多选框分为单个多选框和多个多选框两种场景,单个多选框绑定布尔值,控制是否选中;多个多选框绑定数组,选中的选项的value会被添加到数组中。
<template>
<div>
<!-- 单个多选框 -->
<input type="checkbox" id="agree" v-model="isAgree">
<label for="agree">同意用户协议</label>
<p>是否同意协议:{{ isAgree }}</p>
<!-- 多个多选框 -->
<label>爱好:</label>
<input type="checkbox" id="read" value="阅读" v-model="hobbies">
<label for="read">阅读</label>
<input type="checkbox" id="sport" value="运动" v-model="hobbies">
<label for="sport">运动</label>
<input type="checkbox" id="music" value="音乐" v-model="hobbies">
<label for="music">音乐</label>
<p>当前选择的爱好:{{ hobbies }}</p>
</div>
</template>
<script>
export default {
data() {
return {
isAgree: false,
hobbies: []
}
}
}
</script>下拉选择框绑定
下拉选择框分为单选和多选两种,单选时v-model绑定单个值,多选时需要给<select>添加multiple属性,v-model绑定数组。
<template>
<div>
<!-- 单选下拉框 -->
<label>城市:</label>
<select v-model="city">
<option disabled value="">请选择城市</option>
<option value="北京">北京</option>
<option value="上海">上海</option>
<option value="广州">广州</option>
</select>
<p>当前选择的城市:{{ city }}</p>
<!-- 多选下拉框 -->
<label>喜欢的课程:</label>
<select v-model="courses" multiple>
<option value="Vue.js">Vue.js</option>
<option value="React">React</option>
<option value="Angular">Angular</option>
</select>
<p>当前选择的课程:{{ courses }}</p>
</div>
</template>
<script>
export default {
data() {
return {
city: '',
courses: []
}
}
}
</script>v-model修饰符
v-model还提供了几个实用的修饰符,可以处理常见的输入场景:
- .lazy:默认情况下v-model在input事件触发时同步数据,添加.lazy后会在change事件触发时同步,也就是输入框失去焦点或者按回车时才更新数据。
- .number:自动将用户输入的值转为数值类型,如果无法转换则会返回原始值。
- .trim:自动过滤用户输入的首尾空白字符。
<template>
<div>
<!-- .lazy修饰符 -->
<input v-model.lazy="lazyText" placeholder="失去焦点后更新">
<p>lazyText:{{ lazyText }}</p>
<!-- .number修饰符 -->
<input v-model.number="age" type="text" placeholder="输入数字">
<p>age类型:{{ typeof age }}</p>
<!-- .trim修饰符 -->
<input v-model.trim="trimText" placeholder="自动去除首尾空格">
<p>trimText:{{ trimText }}</p>
</div>
</template>
<script>
export default {
data() {
return {
lazyText: '',
age: '',
trimText: ''
}
}
}
</script>v-model的本质
v-model其实是一个语法糖,它背后是v-bind绑定value属性和v-on监听input事件的组合。比如下面的两种写法效果是完全一致的:
<!-- v-model写法 --> <input v-model="msg"> <!-- 等效的原生写法 --> <input :value="msg" @input="msg = $event.target.value">
了解这个本质后,我们也可以自定义组件支持v-model绑定,只需要组件内部触发input事件并传递对应的值即可,这也是Vue.js组件通信的常用方式之一。