Appearance
v-model 是 Vue 最常用的指令之一,实现表单控件和数据之间的双向绑定。
什么是双向绑定?
普通的 :value 只能做到"数据 → 页面"。v-model 能做到:
数据 ↔ 页面:改数据,页面变;用户输入,数据也变。
vue
<template>
<input v-model="message">
<p>你输入的是:{{ message }}</p>
</template>
<script>
export default {
data() {
return { message: '' }
}
}
</script>
你在输入框里打字 → message 自动更新 → 自动刷新。两个方向都是自动的。 💡 Tip:v-model 的本质v-model="message" 等价于同时做了两件事:
:value="message"— 把数据绑到输入框@input="message = $event.target.value"— 监听输入并更新数据 所以它叫"双向绑定",一行顶两行。
不同表单控件的用法
文本框
vue
<input v-model="text">
文本域
vue
<textarea v-model="content"></textarea>
📝 Note:注意<textarea> 不要写 插值,用 v-model。
单选复选框
vue
<input type="checkbox" v-model="checked">
<span>{{ checked ? '已选' : '未选' }}</span>
checked 的值是 true 或 false。
多选复选框(绑定到数组)
vue
<template>
<div>
<input type="checkbox" v-model="hobbies" value="读书"> 读书
<input type="checkbox" v-model="hobbies" value="运动"> 运动
<input type="checkbox" v-model="hobbies" value="音乐"> 音乐
<p>你选了:{{ hobbies }}</p>
</div>
</template>
<script>
export default {
data() {
return {
hobbies: [] // 必须是数组
}
}
}
</script>
单选框
vue
<input type="radio" v-model="gender" value="男"> 男
<input type="radio" v-model="gender" value="女"> 女
下拉列表
vue
<select v-model="city">
<option disabled value="">请选择城市</option>
<option value="beijing">北京</option>
<option value="shanghai">上海</option>
</select>
修饰符
v-model 提供了三个方便的修饰符: | 修饰符 | 作用 | 什么时候用 | | .lazy | 失去焦点时才更新数据(而不是每次输入都更新) | 输入大段文字时减少计算 | | .number | 自动把输入转成数字 | 输入年龄、价格 | | .trim | 自动去掉首尾空格 | 输入用户名、邮箱 |
vue
<input v-model.lazy="message"> <!-- 按回车或失焦才更新 -->
<input v-model.number="age"> <!-- 输入 "25" → age 是数字 25 -->
<input v-model.trim="username"> <!-- " 小明 " → "小明" -->
实际例子:登录表单
vue
<template>
<form @submit.prevent="handleLogin">
<div>
<label>用户名:</label>
<input v-model.trim="username" placeholder="请输入用户名">
</div>
<div>
<label>密码:</label>
<input v-model="password" type="password" placeholder="请输入密码">
</div>
<div>
<label>
<input type="checkbox" v-model="remember"> 记住我
</label>
</div>
<button type="submit">登录</button>
</form>
</template>
<script>
export default {
data() {
return {
username: '',
password: '',
remember: false
}
},
methods: {
handleLogin() {
console.log(`登录:${this.username}, 记住:${this.remember}`)
// 这里发登录请求
}
}
}
</script>
新手常见问题
Q:input 事件和 v-model 冲突吗? A:不会。你仍然可以单独用 @input 做额外的处理,v-model 会继续正常运行。 Q:为什么我的 checkbox 绑定到数组,数据没更新? A:检查你的数组是用 ref 还是 reactive。组合式 API 中如果用 ref([]),用的时候要 .value。 Q:v-model 能绑定 computed 吗? A:能,但需要给 computed 提供 setter。如果只是只读 computed,v-model 会报错。 下一步: 💡 Tip:Composition API 写法(Vue 3)
vue
<script setup>
import { ref } from 'vue'
const message = ref('')
const checked = ref(false)
</script>
模板中 v-model 写法完全不变。 详见: