Checkbox 複選框 - Vant 4
Checkbox 複選框
☑️ 介紹
Checkbox 複選框就像生活中的「購物清單」 📝,讓使用者可以在眾多選項中自由挑選心儀的內容!
無論是表單填寫時的多項選擇、商品篩選時的條件組合,還是批次操作時的便捷管理,Checkbox 都能提供直觀友好的互動體驗。它就像一個貼心的「小助手」,幫助使用者輕鬆表達「我要這個,也要那個」的需求 ✨。
📦 引入
透過以下方式來全域註冊元件,更多註冊方式請參考元件註冊。
import { createApp } from'vue'; import { Checkbox, CheckboxGroup } from'vant'; const app = createApp(); app.use(Checkbox); app.use(CheckboxGroup);🎯 代码演示
基础用法
通过 v-model 就能轻松绑定复选框的勾选状态,就像给开关装上了"遥控器" 🎮!
一个简单的双向绑定,就能让你的应用和用户的选择保持完美同步,再也不用担心状态管理的烦恼 ✨。
import { ref } from'vue'; exportdefault { setup() { const checked = ref(true); return { checked }; }, };禁用状态
有时候某些选项需要"暂时休息"?🛌 通过设置 disabled 属性可以禁用复选框。
这就像给复选框贴上了"请勿打扰"的标签,让用户知道这个选项当前不可用,但依然保持界面的完整性和美观度 🚫。
自定义形状
想要让你的复选框更有个性?🎨 将 shape 属性设置为 square,复选框就会从圆润的"小圆点"变成方正的"小方块"!
不同的形状能传达不同的设计语言,让你的界面更符合品牌调性 📐。
import { ref } from'vue'; exportdefault { setup() { const checked = ref(['a', 'b']); return { checked }; }, };自定义颜色
想要给复选框换个"新衣服"?👗 通过 checked-color 属性就能设置选中状态的专属颜色!
让你的复选框穿上品牌色彩,与整体设计风格完美融合,打造独特的视觉体验 🌈。
自定义大小
复选框也有"大中小号"可选!📏 通过 icon-size 属性可以自由调整图标的大小。
无论是精致小巧的迷你版,还是醒目大方的加大版,都能完美适配你的设计需求 🎯。
自定义图标
不满足于普通的勾选图标?✨ 通过 icon 插槽可以使用任何你喜欢的图标!
甚至可以用可爱的表情、精美的图片,让每次选择都充满惊喜。slotProps 还能帮你判断当前的选中状态,实现动态图标切换 🎭。
import { ref } from'vue'; exportdefault { setup() { const checked = ref(true); return { checked, activeIcon: 'https://fastly.jsdelivr.net/npm/@vant/assets/user-active.png', inactiveIcon: 'https://fastly.jsdelivr.net/npm/@vant/assets/user-inactive.png', }; }, };左侧文本
想要打破常规布局?🔄 将 label-position 属性设置为 'left',就能让文本"搬家"到复选框左侧!
这种反向布局在某些设计场景下能带来意想不到的视觉效果,让界面更加灵活多变 🎨。
禁用文本点击
想要让复选框更"专一"?🎯 设置 label-disabled 属性后,只有点击图标本身才能触发切换!
这就像给复选框设置了"精准模式",避免用户误触文本区域,让交互更加精确可控 🔒。
复选框组
当复选框们需要"团队作战"时,CheckboxGroup 就是最佳的"指挥官"!👥
通过 v-model 数组绑定,可以轻松管理一组复选框的选中状态。就像管理一个"愿望清单",每个选中的项目都会自动加入到数组中 📋。
import { ref } from'vue'; exportdefault { setup() { const checked = ref(['a', 'b']); return { checked }; }, };水平排列
不喜欢复选框们"排队站立"?🚶♂️ 将 direction 属性设置为 horizontal,它们就会"手拉手"水平排列!
这种横向布局特别适合选项较少且文字简短的场景,让界面更加紧凑美观 ➡️。
import { ref } from'vue'; exportdefault { setup() { const checked = ref([]); return { checked }; }, };限制最大可选数
担心用户选择过多?🛡️ 通过 max 属性可以设置复选框组的"选择上限"!
就像限定"最多只能选3个愿望"一样,帮助用户做出更明智的选择,同时保护系统性能 ⚖️。
全选与反选
想要一键掌控所有选项?🎮 通过 CheckboxGroup 实例上的 toggleAll 方法就能实现全选与反选的"魔法操作"!
就像拥有了一个"万能遥控器",可以让所有复选框瞬间听从指挥,大大提升批量操作的效率 ⚡。
import { ref } from'vue'; exportdefault { setup() { const checked = ref([]); const checkboxGroup = ref(null); constcheckAll = () => { checkboxGroup.value.toggleAll(true); } consttoggleAll = () => { checkboxGroup.value.toggleAll(); }, return { checked, checkAll, toggleAll, checkboxGroup, }; }, };搭配单元格组件使用
想要打造更优雅的列表选择体验?✨ 将 Checkbox 与 Cell 组件完美结合!
这种搭配就像给列表穿上了"正装",既保持了选择功能,又提供了更丰富的信息展示空间,特别适合设置页面和选择列表 📱。
import { ref, onBeforeUpdate } from'vue'; exportdefault { setup() { const checked = ref([]); const checkboxRefs = ref([]); consttoggle = (index) => { checkboxRefs.value[index].toggle(); }; onBeforeUpdate(() => { checkboxRefs.value = []; }); return { list: ['a', 'b'], toggle, checked, checkboxRefs, }; }, };不确定状态
有时候选择状态需要表达"既不是全选,也不是全不选"?🤔 indeterminate 属性就能完美展示这种"模糊"状态!
这就像复选框在说"我有点纠结",特别适合表示部分选中的父级选项,让用户一眼就能理解当前的选择情况 🎭。
import { ref } from'vue'; exportdefault { setup() { const list = ['a', 'b', 'c', 'd'] const isCheckAll = ref(false); const checkedResult = ref(['a', 'b', 'd']); const isIndeterminate = ref(true); constcheckAllChange = (val: boolean) => { checkedResult.value = val ? list : [] isIndeterminate.value = false } constcheckedResultChange = (value: string[]) => { const checkedCount = value.length isCheckAll.value = checkedCount === list.length isIndeterminate.value = checkedCount > 0 && checkedCount < list.length } return { list, isCheckAll, checkedResult, checkAllChange, isIndeterminate, checkedResultChange }; }, };API
Checkbox Props
| 参数 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| v-model | 是否为选中状态 | boolean | false |
| name | 标识符,通常为一个唯一的字符串或数字 | any | - |
| shape | 形状,可选值为 square | string | round |
| disabled | 是否禁用复选框 | boolean | false |
| label-disabled | 是否禁用复选框文本点击 | boolean | false |
| label-position | 文本位置,可选值为 left | string | right |
| icon-size | 图标大小,默认单位为 px | *number | string* |
| checked-color | 选中状态颜色 | string | #1989fa |
| bind-group | 是否与复选框组绑定 | boolean | true | | indeterminate | 是否为不确定状态 | boolean | false |
CheckboxGroup Props
| 参数 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| v-model | 所有选中项的标识符 | any[] | - |
| disabled | 是否禁用所有复选框 | boolean | false |
| max | 最大可选数,0 为无限制 | *number | string* |
| direction | 排列方向,可选值为 horizontal | string | vertical |
| icon-size | 所有复选框的图标大小,默认单位为 px | *number | string* |
| checked-color | 所有复选框的选中状态颜色 | string | #1989fa |
| shape v4.6.3 | 形状,可选值为 square | string | round |
Checkbox Events
| 事件名 | 说明 | 回调参数 |
|---|---|---|
| change | 当绑定值变化时触发的事件 | checked: boolean |
| click | 点击复选框时触发 | event: MouseEvent |
CheckboxGroup Events
| 事件名 | 说明 | 回调参数 |
|---|---|---|
| change | 当绑定值变化时触发的事件 | names: any[] |
Checkbox Slots
| 名称 | 说明 | 参数 |
|---|---|---|
| default | 自定义文本 | { checked: boolean, disabled: boolean } |
| icon | 自定义图标 | { checked: boolean, disabled: boolean } |
CheckboxGroup 方法
通过 ref 可以获取到 CheckboxGroup 实例并调用实例方法,详见组件实例方法。
| 方法名 | 说明 | 参数 | 返回值 |
|---|---|---|---|
| toggleAll | 切换所有复选框,传 true 为选中,false 为取消选中,不传参为取反 | *options?: boolean | object* |
toggleAll 方法示例
import { ref } from'vue'; import type { CheckboxGroupInstance } from'vant'; const checkboxGroupRef = ref<CheckboxGroupInstance>(); // 全部反选 checkboxGroupRef?.value.toggleAll(); // 全部选中 checkboxGroupRef?.value.toggleAll(true); // 全部取消 checkboxGroupRef?.value.toggleAll(false); // 全部反选,并跳过禁用的复选框 checkboxGroupRef?.value.toggleAll({ skipDisabled: true, }); // 全部选中,并跳过禁用的复选框 checkboxGroupRef?.value.toggleAll({ checked: true, skipDisabled: true, });Checkbox 方法
通过 ref 可以获取到 Checkbox 实例并调用实例方法,详见组件实例方法。
| 方法名 | 说明 | 参数 | 返回值 |
|---|---|---|---|
| toggle | 切换选中状态,传 true 为选中,false 为取消选中,不传参为取反 | checked?: boolean | - |
类型定义
组件导出以下类型定义:
importtype { CheckboxProps, CheckboxShape, CheckboxInstance, CheckboxLabelPosition, CheckboxGroupProps, CheckboxGroupInstance, CheckboxGroupDirection, CheckboxGroupToggleAllOptions, } from'vant';CheckboxInstance 和 CheckboxGroupInstance 是组件实例的类型,用法如下:
import { ref } from'vue'; importtype { CheckboxInstance, CheckboxGroupInstance } from'vant'; const checkboxRef = ref<CheckboxInstance>(); const checkboxGroupRef = ref<CheckboxGroupInstance>(); checkboxRef.value?.toggle(); checkboxGroupRef.value?.toggleAll();主题定制
样式变量
组件提供了下列 CSS 变量,可用于自定义样式,使用方法请参考 ConfigProvider 组件。
| 名称 | 默认值 | 描述 |
|---|---|---|
| --van-checkbox-size | 20px | - |
| --van-checkbox-border-color | var(--van-gray-5) | - |
| --van-checkbox-duration | var(--van-duration-fast) | - |
| --van-checkbox-label-margin | var(--van-padding-xs) | - |
| --van-checkbox-label-color | var(--van-text-color) | - |
| --van-checkbox-checked-icon-color | var(--van-primary-color) | - |
| --van-checkbox-disabled-icon-color | var(--van-gray-5) | - |
| --van-checkbox-disabled-label-color | var(--van-text-color-3) | - |
| --van-checkbox-disabled-background | var(--van-border-color) | - |
最佳实践
选项设计原则
设计复选框选项时,应该遵循以下原则 📋:
<!-- ✅ 推荐:简洁明了的选项文字 -->
<van-checkbox-group v-model="checked">
<van-checkbox name="apple">苹果</van-checkbox>
<van-checkbox name="banana">香蕉</van-checkbox>
<van-checkbox name="orange">橙子</van-checkbox>
</van-checkbox-group>
<!-- ❌ 避免:过长或模糊的选项描述 -->
<van-checkbox name="fruit">
这是一个非常美味且营养丰富的热带水果选项
</van-checkbox>状态管理最佳实践
合理管理复选框状态能提升用户体验 ✨:
// ✅ 推荐:使用响应式数据管理状态
const selectedItems = ref([]);
const allItems = ['item1', 'item2', 'item3'];
// 全选状态计算
const isAllSelected = computed(() =>
selectedItems.value.length === allItems.length
);
// 部分选中状态计算
const isIndeterminate = computed(() =>
selectedItems.value.length > 0 && !isAllSelected.value
);表单验证集成
<!-- 与表单验证完美结合 -->
<van-form @submit="onSubmit">
<van-field name="agreement" label="用户协议">
<template #input>
<van-checkbox
v-model="form.agreement"
:rules="[{ required: true, message: '请同意用户协议' }]"
>
我已阅读并同意用户协议
</van-checkbox>
</template>
</van-field>
</van-form>性能优化小贴士
大量选项优化
当处理大量复选框时,考虑以下优化策略 🚀:
<!-- 使用虚拟滚动处理大量选项 -->
<van-list v-model:loading="loading" @load="onLoad">
<van-checkbox-group v-model="checked">
<van-checkbox
v-for="item in visibleItems"
:key="item.id"
:name="item.id"
>
{{ item.label }}
</van-checkbox>
</van-checkbox-group>
</van-list>事件处理优化
// ✅ 推荐:使用防抖处理频繁变化
import { debounce } from 'lodash-es';
const handleChange = debounce((value) => {
// 处理选择变化
console.log('选中项:', value);
}, 300);设计建议
视觉层次
- 分组标题:使用清晰的标题区分不同选项组 📚
- 选项间距:保持适当的间距,避免误触 📏
- 状态反馈:提供明确的选中/未选中视觉反馈 👁️
- 禁用状态:使用灰色等视觉提示表示不可用状态 🚫
交互体验
- 响应速度:确保选择操作有即时反馈 ⚡
- 触摸友好:在移动端提供足够大的点击区域 📱
- 键盘导航:支持键盘操作提升无障碍体验 ⌨️
常见问题解决
Q: 如何实现复选框的动态禁用?
<van-checkbox-group v-model="selected">
<van-checkbox
v-for="item in options"
:key="item.id"
:name="item.id"
:disabled="item.disabled || isMaxSelected"
>
{{ item.label }}
</van-checkbox>
</van-checkbox-group>
<script>
const isMaxSelected = computed(() =>
selected.value.length >= maxCount && maxCount > 0
);
</script>Q: 如何实现复选框的条件显示?
<van-checkbox-group v-model="selected">
<van-checkbox
v-for="item in filteredOptions"
:key="item.id"
:name="item.id"
>
{{ item.label }}
</van-checkbox>
</van-checkbox-group>
<script>
const filteredOptions = computed(() =>
options.filter(item => item.visible !== false)
);
</script>Q: 如何实现复选框的自定义样式?
<van-checkbox
v-model="checked"
:checked-color="customColor"
:icon-size="customSize"
>
<template #icon="{ checked }">
<img :src="checked ? activeIcon : inactiveIcon" />
</template>
自定义图标复选框
</van-checkbox>Q: 如何处理复选框的异步数据?
// 异步加载选项数据
const loadOptions = async () => {
loading.value = true;
try {
const response = await api.getOptions();
options.value = response.data;
} catch (error) {
console.error('加载选项失败:', error);
} finally {
loading.value = false;
}
};高级用法示例
树形结构复选框
<template>
<div class="tree-checkbox">
<van-checkbox
v-model="parentChecked"
:indeterminate="isIndeterminate"
@change="handleParentChange"
>
全部选项
</van-checkbox>
<van-checkbox-group
v-model="childrenChecked"
@change="handleChildrenChange"
>
<van-checkbox
v-for="child in children"
:key="child.id"
:name="child.id"
>
{{ child.label }}
</van-checkbox>
</van-checkbox-group>
</div>
</template>搜索过滤复选框
<template>
<div>
<van-search
v-model="searchText"
placeholder="搜索选项"
@input="handleSearch"
/>
<van-checkbox-group v-model="selected">
<van-checkbox
v-for="item in filteredOptions"
:key="item.id"
:name="item.id"
>
<span v-html="highlightText(item.label)"></span>
</van-checkbox>
</van-checkbox-group>
</div>
</template>