尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

antd Tag.CheckableTag 实战:实现类似 Checkbox 的完全受控可勾选标签

antd Tag.CheckableTag 实战:实现类似 Checkbox 的完全受控可勾选标签 前端UI组件设计系统【免费下载链接】ant-designAn enterprise-class UI design language and React UI library项目地址https://gitcode.com/gh_mirrors/ant/ant-design点击查看免费下载Tag.CheckableTag是 ant-design 中 Tag 组件的可勾选形态它模拟 Checkbox 的交互点击即可切换选中效果适用于分类筛选、偏好选择等场景。本文以仓库中 Checkable 示例文档 为主线结合 示例源码、组件实现、样式与测试用例完整讲解其用法、API、受控原理与最佳实践。读完你不仅能快速落地一个多选标签筛选功能还能理解完全受控、无内部状态这一设计背后的源码逻辑与测试保障。一、从 Demo 文档看 CheckableTag 的核心能力仓库中的 checkable.md 用一句话精准概括了这个组件的定位可通过CheckableTag实现类似 Checkbox 的效果点击切换选中效果。该组件为完全受控组件不支持非受控用法。这段描述包含两个关键信息点交互形态CheckableTag 在外观上是标签Tag在交互上却与 Checkbox 等价——用户点击标签选中状态随之切换受控约束它是一个绝对受控组件absolute controlled component不存在非受控模式。这意味着选中状态完全由外部传入的checked属性决定组件内部不维护任何选中状态。从组件挂载方式看CheckableTag 并不是独立导出的组件而是作为 Tag 的静态属性挂载。在 components/tag/index.tsx 中可以清晰看到这一结构const Tag InternalTag as TagType; Tag.CheckableTag CheckableTag;因此在实际使用中你需要通过Tag.CheckableTag或import { Tag } from antd后使用Tag.CheckableTag来访问它该 API 同样收录在 Tag 官方文档 的示例列表与 API 表格中。二、快速上手完整 Demo 代码逐行解析仓库中的 checkable.tsx 提供了一个典型的兴趣分类多选场景代码如下import React from react; import { Flex, Tag } from antd; const tagsData [Movies, Books, Music, Sports]; const App: React.FC () { const [selectedTags, setSelectedTags] React.useStatestring[]([Movies]); const handleChange (tag: string, checked: boolean) { const nextSelectedTags checked ? [...selectedTags, tag] : selectedTags.filter((t) t ! tag); console.log(You are interested in: , nextSelectedTags); setSelectedTags(nextSelectedTags); }; return ( Flex gap{4} wrap aligncenter spanCategories:/span {tagsData.mapReact.ReactNode((tag) ( Tag.CheckableTag key{tag} checked{selectedTags.includes(tag)} onChange{(checked) handleChange(tag, checked)} {tag} /Tag.CheckableTag ))} /Flex ); }; export default App;逐段拆解这段代码的关键逻辑状态提升到父组件selectedTags是一个string[]保存在App组件中初始值为[Movies]。这正是完全受控的落地方式——数据源唯一组件自身不持有状态受控绑定每个标签的checked{selectedTags.includes(tag)}由父级数组实时推导保证渲染结果始终与状态一致onChange 反推状态点击标签时onChange会收到布尔值checked。handleChange依据该值决定追加还是过滤移除然后调用setSelectedTags更新状态形成点击 → 回调 → 更新 checked → 重新渲染的完整闭环布局辅助外层使用Flexgap{4} wrap aligncenter让标签横向排布、空间不足时自动换行并保持垂直居中。该示例已在 Tag 文档中注册为名为 Checkable 的演示见 index.en-US.md 第 25 行的code src./demo/checkable.tsxCheckable/code可直接在文档站点中交互体验。三、API 详解CheckableTag 的 Props 一览Tag 官方文档 中Tag.CheckableTag一节给出了核心 API属性说明类型默认值checked标签选中状态booleanfalseonChange选中状态变化时触发的回调(checked) void-结合 CheckableTag.tsx 中导出的CheckableTagProps接口实际可用的 Props 比文档表格更完整属性说明类型默认值checked受控选中状态必传boolean-onChange点击后选中状态切换回调(checked: boolean) void-onClick原生点击事件回调(e: React.MouseEventHTMLSpanElement, MouseEvent) void-prefixCls自定义样式类名前缀string由 ConfigProvider 提供className附加到根元素的自定义类名string-style根元素内联样式React.CSSProperties-children标签内容React.ReactNode-几点需要注意的细节checked是必填属性。TypeScript 类型定义中它是非可选required字段如果你漏传会在编译期直接报错这是完全受控在类型层面的强制约束onChange与onClick都会触发。从源码的点击处理可以看到二者是串联调用关系详见下一节prefixCls与全局主题联动组件内部通过ConfigContext的getPrefixCls(tag, customizePrefixCls)获取类名前缀默认渲染为ant-tag相关类名支持 ConfigProvider 全局定制。四、完全受控的底层原理源码级解析要理解完全受控、无内部状态直接阅读 CheckableTag.tsx 是最快的方式。整个组件只有约 60 行核心逻辑集中在点击处理与类名计算上。1. 点击处理状态翻转的提议而非执行const handleClick (e: React.MouseEventHTMLSpanElement, MouseEvent) { onChange?.(!checked); onClick?.(e); };点击发生时组件只会做两件事将当前checked取反后的新值通过onChange?.(!checked)抛给父组件——这是提议状态切换而不是直接改内部状态继续调用onClick?.(e)转发原生事件。组件本身没有任何useStatechecked完全来自 props。因此如果你在onChange中没有把新值写回checked界面不会发生任何变化。这既是受控组件的通用特征也是 CheckableTag 最容易被新手踩坑的地方。2. 类名计算选中态如何反映到 DOMconst cls classNames( prefixCls, ${prefixCls}-checkable, { [${prefixCls}-checkable-checked]: checked, }, tag?.className, className, hashId, cssVarCls, );根元素上始终存在ant-tag与ant-tag-checkable两个类名当checked为true时追加ant-tag-checkable-checked。tag?.className来自ConfigContext中的 Tag 全局配置可用于全局统一调整标签样式hashId与cssVarCls则服务于 cssinjs 的样式隔离与 CSS 变量方案由 useStyle 生成。3. ref 与渲染结构组件使用React.forwardRefHTMLSpanElement, CheckableTagProps渲染的是一个原生spanref 可直接拿到 DOM 节点。测试用例 index.test.tsx 验证了ref.current instanceof HTMLSpanElement为真且与document.querySelector(.ant-tag)指向同一节点。五、选中态样式与交互反馈从源码看视觉实现CheckableTag 的视觉反馈由 components/tag/style/index.ts 中的-checkable样式块定义规则如下状态视觉表现使用的 Design Token默认未选中背景与边框透明鼠标变为手型cursor: pointer-未选中悬停文字变为主色背景填充浅色colorPrimary、colorFillSecondary选中checked背景填充主色文字变白colorPrimary、colorTextLightSolid选中悬停背景加深为主色 Hover 值colorPrimaryHover按下active背景加深为主色 Active 值colorPrimaryActive对应源码片段-checkable: { backgroundColor: transparent, borderColor: transparent, cursor: pointer, [:not(${componentCls}-checkable-checked):hover]: { color: token.colorPrimary, backgroundColor: token.colorFillSecondary, }, :active, -checked: { color: token.colorTextLightSolid }, -checked: { backgroundColor: token.colorPrimary, :hover: { backgroundColor: token.colorPrimaryHover }, }, :active: { backgroundColor: token.colorPrimaryActive }, },由此可见CheckableTag 的选中态完全基于 antd 主题 Token 派生colorPrimary一族控制主色梯度colorFillSecondary控制悬停底色colorTextLightSolid控制选中态文字颜色。这意味着通过 ConfigProvider 或主题定制修改colorPrimaryCheckableTag 的选中外观会自动跟随主题变化无需额外适配。六、测试验证行为如何被保证仓库在 components/tag/tests/index.test.tsx 中对 CheckableTag 建立了专门的测试分组可以视为组件契约的权威说明onChange 触发渲染checked{false}的 CheckableTag 后模拟点击断言onChange被以参数true调用expect(onChange).toHaveBeenCalledWith(true)验证点击切换的取值方向正确onClick 触发点击根元素后onClick被调用验证事件转发逻辑ref 支持断言 ref 指向的HTMLSpanElement与.ant-tag查询结果一致且文本内容正确RTL 兼容rtlTest(() Tag.CheckableTag checked{false} /)验证组件在 RTL 方向下渲染正常。此外快照测试 demo.test.ts.snap 记录了 checkable 示例的完整渲染结果选中的 Movies 标签类名为ant-tag ant-tag-checkable ant-tag-checkable-checked其余三个标签仅含ant-tag ant-tag-checkable从 DOM 层面印证了受控选中态的正确输出。七、典型使用场景与注意事项典型场景多选分类筛选。这是 CheckableTag 最自然的用法——把一批标签当作过滤器选中代表纳入筛选范围。上文的 Demo 即是最小实现selectedTags数组即筛选条件集合onChange中通过包含则追加、不包含则移除的二元分支维护数组。实战中需要牢记的几点必须维护checked否则点击无效受控意味着状态单向流动。若onChange中不调用setState更新selectedTags标签的选中态永远不会变化这是 CheckableTag 与普通 Tag 最大的行为差异区分onChange与onClickonChange接收布尔值用于状态同步适合绑定受控逻辑onClick透传原始鼠标事件适合埋点、阻止冒泡等场景。二者都会触发且onChange先于onClick执行与普通 Tag 的差异普通 Tag 内部用useState维护visible可见性状态并有closable、color、icon、bordered等丰富的展示型 API而 CheckableTag 剥离了所有内部状态仅保留checkedonChange这组受控契约专攻可选择场景。二者不可混用——不要在 CheckableTag 上使用closable或color属性它不提供这些能力无障碍与语义CheckableTag 渲染的是span而非原生button如需更严格的键盘可访问性可在外层补充语义化处理例如配合aria-pressed具体以业务可访问性要求为准。八、延伸阅读想深入这一主题推荐继续研读仓库内以下资源示例文档Checkable 示例的双语文档说明本文的主题文档示例源码可直接复制运行的完整多选示例CheckableTag 组件实现约 60 行的受控组件核心源码Tag 组件入口查看Tag.CheckableTag的挂载方式与 Tag 完整 APITag 样式源码checkable 各状态的设计 Token 映射Tag 组件测试CheckableTag 行为契约的测试断言Tag 官方文档CheckableTag 的 API 表格与全部示例索引。赞分享前端UI组件设计系统【免费下载链接】ant-designAn enterprise-class UI design language and React UI library项目地址https://gitcode.com/gh_mirrors/ant/ant-design点击查看免费下载相关推荐antd Checkbox 布局实战Checkbox.Group 与 Grid 组合实现多列勾选布局antd Checkbox 布局实战Checkbox.Group 与 Grid 组合实现多列勾选布局 导读 在 ant design 中 Checkbox.前端UI组件设计系统NocoBase 勾选Checkbox字段详解boolean 存储、值解析与筛选实现NocoBase 勾选Checkbox字段详解boolean 存储、值解析与筛选实现 勾选Checkbox字段是 NocoBase 中用于保存二选一布低代码后端前端人工智能AI 应用工作流自动化antd Tree 组件基础用法详解可勾选、可选中、禁用与默认展开实战指南antd Tree 组件基础用法详解可勾选、可选中、禁用与默认展开实战指南 导读 本文围绕 Ant DesignantdTree 树形控件的基本用法展前端UI组件设计系统上一篇Elixir项目中Logger配置的注意事项下一篇解决Vite项目中vitejs/plugin-legacy插件在旧版浏览器中的Symbol兼容性问题创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表