Taro Checkbox 组件全解析:从属性 API 到多端底层实现
Taro 是支持 React/Vue 等框架编写小程序、H5、React Native 等应用的开放式跨端跨框架解决方案,本文聚焦其内置表单组件 Checkbox 与 CheckboxGroup,以 packages/taro-components/src/components/checkbox/readme.md 的属性文档为骨架,结合 H5 端 Stencil 源码、React/Vue 类型定义与 RN、鸿蒙等平台的实现,系统讲解属性含义、change 事件数据流、默认样式定制与跨端适配细节。读完本文,你将能够熟练使用 Checkbox/CheckboxGroup 完成多选表单、列表勾选、受控回显等实战场景,并理解其在 H5、小程序、RN 等平台上的差异。
一、组件概览:Checkbox 与 CheckboxGroup 的分工
Checkbox(多选项目)与 CheckboxGroup(多项选择器)是 Taro 表单体系(classification: forms)中的一对基础组件,二者配合使用:
Checkbox负责单个选项的渲染与勾选状态展示;CheckboxGroup作为容器收集所有子Checkbox,并在选中项变化时统一对外抛出change事件,事件detail为value: [选中的 checkbox 的 value 的数组]。
在组件源码层面,二者分别实现为两个独立的 Stencil 自定义元素:
taro-checkbox-core:见 checkbox.tsx;taro-checkbox-group-core:见 checkbox-group.tsx;
统一通过 index.ts 的 export * from './checkbox-group'、export * from './checkbox' 导出,并由 components/index.ts 汇总注册。因此在使用时,既可以直接引用 Checkbox / CheckboxGroup,也可以直接书写 taro-checkbox-core / taro-checkbox-group-core 自定义标签。
二、Checkbox 属性详解
Checkbox 支持的属性(以官方 readme 属性表为基础,并补充类型定义中的扩展属性)如下:
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| value | String | false | <Checkbox/> 标识,选中时触发 <CheckboxGroup/> 的 change 事件,并携带 <Checkbox/> 的 value |
| checked | Boolean | false | 当前是否选中,可用来设置默认选中 |
| disabled | Boolean | false | 是否禁用 |
| color | Color | false | checkbox 的颜色,同 css 的 color |
| bindchange | EventHandle | 选中项发生变化时触发 change 事件 | |
| name | String | - | Checkbox 的名字(H5、鸿蒙端支持) |
| nativeProps | Object | - | 透传到内部 H5 标签上的原生属性(H5、Harmony Hybrid 端支持) |
| ariaLabel | String | - | 无障碍访问的属性额外描述(QQ 端支持) |
1. value:选项的唯一标识
value 是每个 Checkbox 的身份标识。选中某个选项后,其 value 会作为数组元素出现在 CheckboxGroup 的 change 事件中。从源码看,checkbox.tsx 中 value 被声明为 @Prop({ mutable: true }) value: string | number = '',即允许后续修改,且默认值为空字符串。务必为每个选项设置不重复的 value,否则无法区分用户勾选了哪些项。
2. checked:受控与默认选中
checked 用于控制当前是否选中,可直接传布尔值实现默认选中或受控选中。源码中 @Prop() checked = false,默认未选中。该属性会直接映射到底层 <input type="checkbox"> 的 checked 属性:
<input
type='checkbox'
value={value}
name={name}
class='taro-checkbox_checked'
style={{ color }}
checked={checked}
disabled={disabled}
onChange={this.handleChange}
{...nativeProps}
/>
在 React 端可配合 onChange 更新状态,实现选中/取消的动态回显。
3. disabled:禁用选项
disabled 为 true 时选项不可交互,样式上通常呈现置灰效果,同时底层 <input> 的 disabled 属性也被置位,从根源上阻止用户点击。
4. color:自定义勾选颜色
color 接受与 CSS color 一致的颜色值(如 #1aad19、red、rgb(...)),直接作为内联 style={{ color }} 应用到 <input> 上。结合 style/index.scss 中 .taro-checkbox_checked 的样式定义:
&_checked {
display: inline-block;
position: relative;
top: 5px;
border: 1px solid #d1d1d1;
border-radius: 3px;
width: 23px;
height: 23px;
min-height: 0;
appearance: none;
outline: 0;
background-color: #fff;
vertical-align: 0;
font-size: 23px;
color: #1aad19;
&:checked::before {
/* 使用 weui 字体图标 \EA08 绘制勾选标记 */
content: '\EA08';
transform: translate(-50%, -48%) scale(0.73);
/* ... */
}
}
可以看到 H5 端默认勾选颜色为微信绿 #1aad19,勾选标记使用 weui 字体图标(font-family: weui,字形码 \EA08),并对 appearance: none 去掉了浏览器原生 checkbox 外观,实现统一的多端视觉。修改 color 后,勾选标记颜色会随之变化。
5. name 与 nativeProps:H5 专属扩展
name:作为表单字段名,用于表单提交时标识该字段,类型定义为@supported h5, harmony, harmony_hybrid;nativeProps:用于把任意原生属性透传到内部 H5<input>标签上,例如data-*自定义属性、aria-*无障碍属性等。
6. onChange / bindchange:change 事件
Checkbox 自身的 change 事件由源码中的 @Event({ eventName: 'checkboxchange' }) 声明(见 checkbox.tsx)。需要注意两点:
- H5 端
Checkbox单组件并没有暴露bindchange,而是抛出内部事件名checkboxchange,类型为CustomEvent<{ value: string }>,由上层CheckboxGroup通过@Listen('checkboxchange')监听并聚合; - 在小程序端(weapp 等)
Checkbox没有独立的 change API,选中变化统一由CheckboxGroup的bindchange承接。类型定义中onChange的@supported标注为alipay, h5, rn, harmony, harmony_hybrid,即支付宝、H5、RN 与鸿蒙端可以直接监听单个Checkbox的 change,而微信小程序端需通过CheckboxGroup获取。
三、CheckboxGroup 属性详解
CheckboxGroup 的属性相较简单,只有一个核心事件与一个可选属性:
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| bindchange | EventHandle | <CheckboxGroup/> 中选中项发生改变时触发 change 事件,detail = value: [选中的 checkbox 的 value 的数组] | |
| name | String | - | 表单组件中加上 name 作为 key(alipay、tt、h5、harmony_hybrid 支持) |
change 事件的数据结构
无论使用哪种框架写法,CheckboxGroup 的 change 事件参数统一为:
{
value: string[] // 所有被勾选 Checkbox 的 value 组成的数组
}
这一点在 CheckboxGroup.d.ts 中与 CommonEventFunction<{ value: string[] }> 签名严格对应,可直接用于类型推导。
四、H5 端源码级实现:事件聚合与 value 收集
CheckboxGroup 的核心逻辑集中在 checkbox-group.tsx,其工作流程清晰地展示了"单个 checkbox → 组内聚合并对外抛事件"的完整链路:
- 监听子组件事件:通过
@Listen('checkboxchange')监听所有taro-checkbox-core抛出的checkboxchange事件,并过滤e.target.tagName !== 'TARO-CHECKBOX-CORE',避免误收其他来源的事件; - 收集选中值:
getValues()遍历组内所有taro-checkbox-core,取出其内部<input>,过滤checkbox?.checked === true的项,再映射为element.value数组:getValues (childList: NodeListOf<HTMLTaroCheckboxCoreElement>) { return Array.from(childList) .filter(element => { const checkbox: HTMLInputElement | null = element.querySelector('input') return checkbox?.checked }) .map(element => element.value) } - 聚合后对外抛事件:将收集到的数组包装为
{ value: this.#value }并通过onChange.emit发出,事件名即为change; - 自动设置 name:
componentDidLoad阶段,若用户未显式传name,则使用Date.now().toString(36)生成唯一 name 并批量设置到所有子Checkbox上,保证同名分组(原生表单语义); - 暴露 value 属性:通过
Object.defineProperty为组件宿主元素定义value的 getter(懒计算),方便在 H5 侧以命令式方式直接读取当前选中集合。
这段实现说明:CheckboxGroup 并不重新渲染子元素,而是完全基于 DOM 查询(querySelectorAll)与事件监听完成聚合,这也正是 H5 端自定义元素架构下"容器组件"的典型做法。
五、React 与 Vue 端完整用法示例
基于 Checkbox.d.ts 与 CheckboxGroup.d.ts 中的官方示例,以下为 React 写法:
import { Component } from 'react'
import { Checkbox, CheckboxGroup, View, Text, Label } from '@tarojs/components'
export default class PageCheckbox extends Component {
state = {
list: [
{ value: '美国', text: '美国', checked: false },
{ value: '中国', text: '中国', checked: true },
{ value: '巴西', text: '巴西', checked: false },
{ value: '日本', text: '日本', checked: false },
{ value: '英国', text: '英国', checked: false },
{ value: '法国', text: '法国', checked: false }
]
}
render () {
return (
<View className='page-body'>
<View className='page-section'>
<Text>默认样式</Text>
<Checkbox value='选中' checked>选中</Checkbox>
<Checkbox style='margin-left: 20rpx' value='未选中'>未选中</Checkbox>
</View>
<View className='page-section'>
<Text>推荐展示样式</Text>
<CheckboxGroup onChange={e => console.log('选中:', e.detail.value)}>
{this.state.list.map((item, i) => (
<Label className='checkbox-list__label' for={i} key={i}>
<Checkbox className='checkbox-list__checkbox' value={item.value} checked={item.checked}>
{item.text}
</Checkbox>
</Label>
))}
</CheckboxGroup>
</View>
</View>
)
}
}
Vue 3 写法:
<template>
<view class="container">
<view class="page-section">
<text>默认样式</text>
<checkbox value="选中" :checked="true">选中</checkbox>
<checkbox style="margin-left: 20rpx;" value="未选中">未选中</checkbox>
</view>
<view class="page-section">
<text>推荐展示样式</text>
<checkbox-group @change="onChange">
<label v-for="item in list" class="checkbox-list__label">
<checkbox class="checkbox-list__checkbox" :value="item.value" :checked="item.checked">
{{ item.text }}
</checkbox>
</label>
</checkbox-group>
</view>
</view>
</template>
<script>
export default {
data() {
return {
list: [
{ value: '美国', text: '美国', checked: false },
{ value: '中国', text: '中国', checked: true },
// ...
]
}
},
methods: {
onChange(e) {
console.log('选中:', e.detail.value)
}
}
}
</script>
使用要点
- 配合 Label 提升点击区域:官方"推荐展示样式"将
Checkbox包在Label中,点击文字即可切换勾选,是表单列表的推荐实践(for={i}关联Checkbox的 id); - 默认选中:通过
checked属性初始化,如示例中"中国"默认选中; - 事件取值:H5 / 小程序端统一从
e.detail.value取数组;RN 端实现见下文。
六、RN 端与鸿蒙端的跨端实现
作为跨端框架,Taro 在非 H5 平台同样提供了 Checkbox 的实现:
React Native 端
RN 端实现在 taro-components-rn/src/components/Checkbox 与 CheckboxGroup,并配套测试用例 checkbox.spec.tsx(覆盖默认渲染、选中、禁用、change 事件等行为)。RN 端通过 onChange 事件同样返回选中的 value 数组,与 H5 端 API 保持一致,便于业务代码跨端复用。
鸿蒙(HarmonyOS)端
鸿蒙端在多套渲染体系中均有 Checkbox 实现:
- components-harmony/checkbox/index.hml 与对应的 index.js:基于类 HTML 模板渲染;
- components-harmony-ets/checkbox.ets:基于 ArkUI ETS 组件树实现,并通过 index.ets 统一导出。
鸿蒙端的实现同样遵循 value / checked / disabled / color 的属性语义,说明 Taro 将同一套 Checkbox API 映射到了不同平台的底层原生控件之上。
七、样式定制指南
H5 端 Checkbox 的默认样式定义在 style/index.scss,它依赖两个 WeUI 基础样式:
@import '../../../styles/base/variable/weui-button';
@import '../../../styles/widget/weui-cell/weui-cells__group';
定制时通常有两种途径:
- 通过
color属性修改勾选颜色(覆盖内联样式的color,从而改变::before勾选图标的color: inherit); - 通过样式覆盖:为
.taro-checkbox_checked增加自定义 CSS,例如调整尺寸(width/height)、圆角(border-radius)或替换勾选图标(重写content字形码)。
注意 .taro-checkbox_checked 的 appearance: none 会移除原生 checkbox 外观,因此 H5 端完全依赖这套自定义样式呈现勾选状态,跨浏览器表现一致。
八、常见问题与注意事项
- value 必须唯一:change 事件的数组以 value 为标识,重复 value 会导致结果无法区分;
- 小程序端不要依赖单个 Checkbox 的 change:微信小程序端无此 API,请统一使用
CheckboxGroup的bindchange(类型定义中onChange的@supported未包含 weapp); - 受控回显:动态回显选中状态时,将数据源的
checked字段绑定到Checkbox的checked属性,并保证渲染时数据已就绪; - 无障碍(QQ 端):可通过
ariaLabel为选项补充额外描述,提升无障碍体验; - 默认颜色:H5 端默认勾选色为
#1aad19(微信绿),与各小程序平台默认色可能略有差异,多端一致性要求高时建议显式设置color。
九、参考资源
- 组件 readme: checkbox/readme.md
- H5 端实现:checkbox.tsx、checkbox-group.tsx、style/index.scss
- React 类型定义:Checkbox.d.ts、CheckboxGroup.d.ts
- RN 端实现与测试:taro-components-rn/src/components/Checkbox、taro-components-rn/src/components/CheckboxGroup、checkbox.spec.tsx
- 鸿蒙端实现:components-harmony/checkbox/index.hml、components-harmony-ets/checkbox.ets
通过本文可以完成 Checkbox/CheckboxGroup 从属性配置、事件处理到样式定制、跨端适配的完整闭环:H5 端有 Stencil 源码可循,RN 端有独立组件与测试保障,鸿蒙端则映射到原生控件,业务侧只需书写一套 React/Vue 代码,即可在微信、支付宝、百度、抖音、QQ、京东小程序以及 H5、RN、鸿蒙等多端获得一致的勾选交互。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



