一、v-model:双向绑定的核心
v-model
是 Vue 提供的语法糖,用于在表单控件和组件之间创建双向数据绑定。
1. 基本用法:文本框
<template>
<div>
<input v-model="message" placeholder="请输入内容">
<p>你输入的内容:{{ message }}</p>
</div>
</template>
<script>
export default {
data() {
return {
message: ''
}
}
}
</script>
✅
v-model
会自动监听input
事件,并更新message
的值。
二、常见表单控件的数据收集
1. 多行文本(textarea)
<textarea v-model="content" placeholder="请输入描述"></textarea>
<p>内容:{{ content }}</p>
✅
v-model
在textarea
中同样适用,无需value
属性。
2. 复选框(checkbox)
单个复选框(布尔值)
<input type="checkbox" v-model="isAgree">
<label>我同意用户协议</label>
<p>是否同意:{{ isAgree }}</p>
data() {
return {
isAgree: false
}
}
多个复选框(数组)
<div>
<input type="checkbox" v-model="hobbies" value="reading" id="reading">
<label for="reading">阅读</label>
<input type="checkbox" v-model="hobbies" value="music" id="music">
<label for="music">音乐</label>
<input type="checkbox" v-model="hobbies" value="sports" id="sports">
<label for="sports">运动</label>
</div>
<p>爱好:{{ hobbies }}</p>
data() {
return {
hobbies: [] // 初始为空数组
}
}
✅
hobbies
数组将包含所有被选中的value
值。
3. 单选框(radio)
<div>
<input type="radio" v-model="gender" value="male" id="male">
<label for="male">男</label>
<input type="radio" v-model="gender" value="female" id="female">
<label for="female">女</label>
</div>
<p>性别:{{ gender }}</p>
data() {
return {
gender: '' // 初始为空
}
}
✅
v-model
绑定到同一个变量,value
决定选中时的值。
4. 下拉选择框(select)
单选
<select v-model="city">
<option value="">请选择城市</option>
<option value="beijing">北京</option>
<option value="shanghai">上海</option>
<option value="guangzhou">广州</option>
</select>
<p>城市:{{ city }}</p>
多选(添加 multiple
)
<select v-model="skills" multiple>
<option value="vue">Vue</option>
<option value="react">React</option>
<option value="angular">Angular</option>
</select>
<p>技能:{{ skills }}</p>
data() {
return {
skills: []
}
}
✅ 多选时
v-model
绑定的是数组。
三、v-model 的修饰符
Vue 提供了多个修饰符,简化常见操作。
1. .lazy
:从 input
改为 change
事件
<input v-model.lazy="message" placeholder="失去焦点时更新">
✅ 减少频繁更新,适用于搜索框等场景。
2. .number
:自动将输入值转换为数字
<input v-model.number="age" type="number" placeholder="年龄">
✅ 即使输入是字符串,
age
也会是Number
类型。
3. .trim
:自动去除首尾空格
<input v-model.trim="username" placeholder="用户名">
✅ 防止用户误输入空格,提升数据质量。
四、表单提交与数据收集
1. 使用 @submit.prevent
阻止默认提交
<form @submit.prevent="handleSubmit">
<input v-model="form.username" placeholder="用户名" required>
<input v-model="form.password" type="password" placeholder="密码" required>
<button type="submit">登录</button>
</form>
export default {
data() {
return {
form: {
username: '',
password: ''
}
}
},
methods: {
handleSubmit() {
console.log('提交表单:', this.form)
// 发送请求
// this.$http.post('/api/login', this.form)
}
}
}
✅
@submit.prevent
阻止页面刷新,调用handleSubmit
方法。
2. 表单验证(基础版)
methods: {
handleSubmit() {
if (!this.form.username || !this.form.password) {
alert('请填写完整信息')
return
}
console.log('提交成功:', this.form)
}
}
✅ 实际项目中推荐使用 VeeValidate、Element Plus 表单验证等库。
五、v-model 的原理(了解)
v-model
本质上是语法糖,等价于:
<!-- v-model="message" -->
<input
:value="message"
@input="message = $event.target.value"
>
对于组件,v-model
默认监听 modelValue
和 update:modelValue
事件(Vue 3)。
六、Vue 3 Composition API 写法
在 setup()
中,v-model
依然可用,数据通过 ref
定义。
<script>
import { ref } from 'vue'
export default {
setup() {
const form = ref({
username: '',
password: '',
remember: false
})
const handleSubmit = () => {
console.log('提交:', form.value)
}
return {
form,
handleSubmit
}
}
}
</script>
<template>
<form @submit.prevent="handleSubmit">
<input v-model="form.username" placeholder="用户名">
<input v-model="form.password" type="password" placeholder="密码">
<label>
<input v-model="form.remember" type="checkbox"> 记住我
</label>
<button type="submit">登录</button>
</form>
</template>
七、最佳实践与常见问题
✅ 推荐做法
- 使用对象集中管理表单数据(如
form
对象) - 始终添加
.trim
修饰符,避免空格问题 - 复杂表单使用
computed
或watch
处理联动逻辑 - 提交前做基本验证,防止无效请求
❓ 常见问题
1. v-model 不更新?
- 检查数据是否在
data
或ref
中定义 - 避免直接修改数组索引或对象属性(Vue 2)
- 使用
Vue.set
或解构赋值更新
2. 如何重置表单?
resetForm() {
this.form = {
username: '',
password: '',
hobbies: []
}
}
八、总结
控件 | v-model 绑定类型 |
---|---|
文本框 / textarea | 字符串 |
复选框(单) | 布尔值 |
复选框(多) | 数组 |
单选框 | 字符串/数字 |
下拉框(单) | 字符串/数字 |
下拉框(多) | 数组 |
修饰符 | 作用 |
---|---|
.lazy | change 事件触发 |
.number | 转换为数字 |
.trim | 去除首尾空格 |
九、结语
感谢您的阅读!如果你有任何疑问或想要分享的经验,请在评论区留言交流!