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>