单选框和复选框是表单中常用的选择控件。虽然使用
v-model绑定很简单,但不同场景下绑定值的方式有所不同,需要理解其中的区别。
单个复选框绑定布尔值,选中为 true,未选中为 false:
<div id="app">
<label>
<input type="checkbox" v-model="agree">
同意用户协议
</label>
<p>状态:{{ agree }}</p>
</div>
<script>
new Vue({
el: '#app',
data: {
agree: false
}
})
</script>
使用 true-value 和 false-value 自定义选中/未选中的值:
<div id="app">
<label>
<input
type="checkbox"
v-model="status"
true-value="yes"
false-value="no"
>
订阅邮件
</label>
<p>状态:{{ status }}</p>
</div>
<script>
new Vue({
el: '#app',
data: {
status: 'no'
}
})
</script>
选中时 status 为 'yes',未选中时为 'no'。
多个复选框绑定同一个数组,选中的值会自动添加到数组中:
<div id="app">
<p>选择你喜欢的水果:</p>
<label>
<input type="checkbox" v-model="fruits" value="apple"> 苹果
</label>
<label>
<input type="checkbox" v-model="fruits" value="banana"> 香蕉
</label>
<label>
<input type="checkbox" v-model="fruits" value="orange"> 橙子
</label>
<p>已选择:{{ fruits }}</p>
</div>
<script>
new Vue({
el: '#app',
data: {
fruits: [] // 初始化为空数组
}
})
</script>
选中苹果和香蕉后,fruits 为 ['apple', 'banana']。
使用 v-bind 动态绑定值:
<div id="app">
<label v-for="item in items" :key="item.id">
<input
type="checkbox"
v-model="selected"
:value="item"
>
{{ item.name }}
</label>
<pre>{{ selected }}</pre>
</div>
<script>
new Vue({
el: '#app',
data: {
items: [
{ id: 1, name: '选项一' },
{ id: 2, name: '选项二' },
{ id: 3, name: '选项三' }
],
selected: []
}
})
</script>
选中的是完整的对象,而不只是字符串值。
<div id="app">
<label>
<input
type="checkbox"
:checked="allSelected"
@change="toggleAll"
>
全选
</label>
<hr>
<label v-for="item in items" :key="item.id">
<input
type="checkbox"
v-model="selected"
:value="item.id"
>
{{ item.name }}
</label>
<p>已选择:{{ selected.length }} / {{ items.length }}</p>
</div>
<script>
new Vue({
el: '#app',
data: {
items: [
{ id: 1, name: '选项一' },
{ id: 2, name: '选项二' },
{ id: 3, name: '选项三' },
{ id: 4, name: '选项四' }
],
selected: []
},
computed: {
allSelected: function() {
return this.items.length > 0 &&
this.selected.length === this.items.length
}
},
methods: {
toggleAll: function() {
if (this.allSelected) {
this.selected = []
} else {
this.selected = this.items.map(item => item.id)
}
}
}
})
</script>
单选框绑定单个值,选中的 value 会赋给绑定变量:
<div id="app">
<p>选择性别:</p>
<label>
<input type="radio" v-model="gender" value="male"> 男
</label>
<label>
<input type="radio" v-model="gender" value="female"> 女
</label>
<p>已选择:{{ gender }}</p>
</div>
<script>
new Vue({
el: '#app',
data: {
gender: ''
}
})
</script>
<div id="app">
<label v-for="option in options" :key="option.value">
<input
type="radio"
v-model="selected"
:value="option.value"
>
{{ option.label }}
</label>
<p>已选择:{{ selected }}</p>
</div>
<script>
new Vue({
el: '#app',
data: {
options: [
{ value: 'option1', label: '选项一' },
{ value: 'option2', label: '选项二' },
{ value: 'option3', label: '选项三' }
],
selected: ''
}
})
</script>
<div id="app">
<label v-for="plan in plans" :key="plan.id">
<input
type="radio"
v-model="selectedPlan"
:value="plan"
>
{{ plan.name }} - ¥{{ plan.price }}/月
</label>
<div v-if="selectedPlan">
<h3>已选择:{{ selectedPlan.name }}</h3>
<p>价格:¥{{ selectedPlan.price }}/月</p>
<p>描述:{{ selectedPlan.description }}</p>
</div>
</div>
<script>
new Vue({
el: '#app',
data: {
plans: [
{ id: 1, name: '基础版', price: 9.9, description: '适合个人用户' },
{ id: 2, name: '专业版', price: 29.9, description: '适合小型团队' },
{ id: 3, name: '企业版', price: 99.9, description: '适合大型企业' }
],
selectedPlan: null
}
})
</script>
<div id="app">
<h3>设置用户权限</h3>
<div class="permission-group">
<h4>基础权限</h4>
<label>
<input type="checkbox" v-model="permissions" value="read">
查看内容
</label>
<label>
<input type="checkbox" v-model="permissions" value="write">
编辑内容
</label>
</div>
<div class="permission-group">
<h4>管理权限</h4>
<label>
<input type="checkbox" v-model="permissions" value="delete">
删除内容
</label>
<label>
<input type="checkbox" v-model="permissions" value="admin">
管理用户
</label>
</div>
<p>当前权限:{{ permissions.join(', ') || '无' }}</p>
</div>
<script>
new Vue({
el: '#app',
data: {
permissions: ['read'] // 默认有查看权限
}
})
</script>
<div id="app">
<h3>请评分</h3>
<div class="rating">
<label v-for="n in 5" :key="n">
<input
type="radio"
v-model="rating"
:value="n"
class="rating-input"
>
<span class="rating-star" :class="{ active: n <= rating }">★</span>
</label>
</div>
<p>评分:{{ rating }} 星</p>
</div>
<style>
.rating-input {
display: none;
}
.rating-star {
font-size: 32px;
color: #ddd;
cursor: pointer;
}
.rating-star.active {
color: #f5a623;
}
</style>
<script>
new Vue({
el: '#app',
data: {
rating: 0
}
})
</script>
<div id="app">
<h3>选择标签</h3>
<div class="tags">
<label
v-for="tag in allTags"
:key="tag"
class="tag-label"
:class="{ selected: selectedTags.includes(tag) }"
>
<input
type="checkbox"
v-model="selectedTags"
:value="tag"
class="tag-input"
>
{{ tag }}
</label>
</div>
<p>已选标签:{{ selectedTags.join(', ') || '无' }}</p>
</div>
<style>
.tag-input {
display: none;
}
.tag-label {
display: inline-block;
padding: 4px 12px;
margin: 4px;
border: 1px solid #ddd;
border-radius: 16px;
cursor: pointer;
}
.tag-label.selected {
background: #42b983;
color: white;
border-color: #42b983;
}
</style>
<script>
new Vue({
el: '#app',
data: {
allTags: ['前端', '后端', 'Vue', 'React', 'Node.js', 'Python', 'Java'],
selectedTags: []
}
})
</script>
<div id="app">
<div class="switch-group">
<span>夜间模式</span>
<label class="switch">
<input type="checkbox" v-model="darkMode">
<span class="slider"></span>
</label>
</div>
<div class="switch-group">
<span>消息通知</span>
<label class="switch">
<input type="checkbox" v-model="notifications">
<span class="slider"></span>
</label>
</div>
<div class="switch-group">
<span>自动播放</span>
<label class="switch">
<input type="checkbox" v-model="autoPlay">
<span class="slider"></span>
</label>
</div>
</div>
<style>
.switch {
position: relative;
display: inline-block;
width: 50px;
height: 26px;
}
.switch input {
opacity: 0;
width: 0;
height: 0;
}
.slider {
position: absolute;
cursor: pointer;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: #ccc;
transition: .3s;
border-radius: 26px;
}
.slider:before {
position: absolute;
content: "";
height: 20px;
width: 20px;
left: 3px;
bottom: 3px;
background-color: white;
transition: .3s;
border-radius: 50%;
}
input:checked + .slider {
background-color: #42b983;
}
input:checked + .slider:before {
transform: translateX(24px);
}
.switch-group {
display: flex;
justify-content: space-between;
align-items: center;
padding: 12px 0;
border-bottom: 1px solid #eee;
}
</style>
<script>
new Vue({
el: '#app',
data: {
darkMode: false,
notifications: true,
autoPlay: false
}
})
</script>
复选框数组初始化
多个复选框绑定数组时,必须初始化为空数组,否则会绑定为布尔值:
// ✅ 正确
data: {
selected: []
}
// ❌ 错误(会变成布尔值绑定)
data: {
selected: ''
}
单选框默认选中
设置初始值即可默认选中:
data: {
gender: 'male' // 默认选中男
}
单选框和复选框的处理要点:
true-value/false-valuevalue 赋给变量v-bind 绑定对象或动态值