☰
微信小程序 TDesign Tag 标签组件实战指南:从属性 API 到源码级样式定制
2026/10/15 17:55:20 网站建设 项目流程
  • 示例工程
  • 小程序
  • 前端

【免费下载链接】miniprogram-demo

微信小程序组件 / API / 云开发示例

项目地址:https://gitcode.com/gh_mirrors/mi/miniprogram-demo
点击查看免费下载

本文以 miniprogram-demo 仓库中集成的 TDesign 小程序 Tag 标签组件为核心,系统讲解其引入方式、Tag与CheckTag两套组件 API、事件体系、外部样式类,以及基于 CSS 变量和源码实现的深度定制方法。读完本文,你将掌握在微信小程序中快速搭建展示型、可关闭、可选中标签的完整方案,并理解标签样式在各尺寸、主题、变体下是如何通过源码与设计令牌(Design Token)联动生效的。

组件定位与使用场景

Tag(标签)组件用于表明主体的类目、属性或状态,是界面信息层级中成本最低、复用率最高的视觉要素之一。在本仓库中,它被封装为 TDesign 风格的小程序原生组件,提供两个核心形态:

  • Tag:展示型标签,支持主题色、尺寸、形状、变体、图标、可关闭、禁用、最大宽度等能力;
  • CheckTag:可选中标签,支持checked/default-checked受控与非受控两种状态管理,以及点击切换时的事件回调。

组件类型定义中明确其用途为"用于表明主体的类目,属性或状态",实际常见于订单状态角标、商品分类筛选、文章话题标注、表单多选标签等场景。

引入方式:全局与局部

该组件采用标准小程序自定义组件封装,引入方式与普通组件一致。

全局引入:在 miniprogram 根目录的app.json的usingComponents中配置,所有页面均可直接使用:

"usingComponents": { "t-tag": "tdesign-miniprogram/tag/tag", "t-check-tag": "tdesign-miniprogram/check-tag/check-tag" }

局部引入:在需要使用的页面或组件目录的index.json(或对应页面.json)中按同样方式配置,仅对当前页面生效。

需要说明的是,当前仓库快照中实际包含的是 tag 组件目录,check-tag组件在仓库中尚未收录,上例中t-check-tag的路径来自 README.md 的引入示例,落地使用时请确保对应组件包已随tdesign-miniprogram依赖完整安装。引入后,在开发者工具中依次执行npm i、构建 npm 包,并勾选"将 JS 编译成 ES5",即可正常预览效果。

Tag 组件 API 全解析

组件源码位于 tag.js,其属性定义集中在 props.js,类型声明见 type.d.ts。

Tag Props

| 名称 | 类型 | 默认值 | 描述 | 必传 | | -- | -- | -- | -- | -- | | style | Object | - | 样式 | N | | custom-style | Object | - | 样式,一般用于开启虚拟化组件节点场景 | N | | closable | Boolean / Object / Slot | false | 标签是否可关闭,也可传入关闭图标对象或自定义关闭插槽 | N | | disabled | Boolean | false | 标签禁用态,失效标签不能触发事件。默认风格(theme=default)才有禁用态 | N | | icon | String / Object / Slot | - | 标签中的图标,可自定义图标呈现 | N | | max-width | String / Number | - | 标签最大宽度,宽度超出后会出现省略号。示例:'50px'/80| N | | shape | String | square | 标签类型,有三种:方形、圆角方形、标记型。可选项:square/round/mark| N | | size | String | medium | 标签尺寸。可选项:small/medium/large/extra-large| N | | theme | String | default | 组件风格,用于描述组件不同的应用场景。可选项:default/primary/warning/danger/success| N | | variant | String | dark | 标签风格变体。可选项:dark/light/outline/light-outline| N |

在 props.js 中可以印证这些默认值:closable与disabled默认均为false,shape默认square,size默认medium,theme默认default,variant默认dark;而icon、maxWidth的类型被定义为null(即不限定类型),以兼容字符串、对象等不同传参形态。

Tag Events

| 名称 | 参数 | 描述 | | -- | -- | -- | | click | - | 点击时触发 | | close | - | 如果关闭按钮存在,点击关闭按钮时触发 |

事件在 tag.js 的handleClick/handleClose方法中实现:两个方法都会先检查disabled状态,禁用态下直接return,不触发任何事件;否则通过this.triggerEvent('click' / 'close', e)向上抛出。

Tag External Classes

| 类名 | 描述 | | -- | -- | | t-class | 根节点样式类 |

外部样式类由this.externalClasses = ['t-class']声明,可在使用组件的页面中通过t-class="自定义类"直接给标签根节点追加样式,无需深入组件内部。

CheckTag 组件 API 全解析

CheckTag是带选中态的标签变体,适合表达"可切换的过滤条件"等交互场景。

CheckTag Props

| 名称 | 类型 | 默认值 | 描述 | 必传 | | -- | -- | -- | -- | -- | | style | Object | - | 样式 | N | | custom-style | Object | - | 样式,一般用于开启虚拟化组件节点场景 | N | | checked | Boolean | undefined | 标签选中的状态,默认风格(theme=default)才有选中态 | N | | default-checked | Boolean | undefined | 标签选中的状态,默认风格(theme=default)才有选中态。非受控属性 | N | | closable | Boolean | false | 标签是否可关闭 | N | | content | String / Number / Array / Slot | - | 组件子元素;传入数组时为[选中内容,非选中内容]。TS 类型:string \| number \| string[]| N | | disabled | Boolean | false | 标签禁用态,失效标签不能触发事件。默认风格(theme=default)才有禁用态 | N | | icon | String / Object / Slot | - | 标签图标 | N | | shape | String | square | 标签类型,有三种:方形、圆角方形、标记型。可选项:square/round/mark| N | | size | String | medium | 标签尺寸。可选项:small/medium/large。TS 类型:SizeEnum| N | | variant | String | dark | 标签风格变体(该属性自 0.26.0 版本起提供)。可选项:dark/light/outline/light-outline| N |

checked与default-checked的配合遵循典型的受控/非受控模式:传入checked表示由父级接管选中状态,组件自身不维护内部变更;不传checked而传default-checked时,组件在内部自行维护选中态,适合不需要回写数据的场景。content传数组时的语义是"第 0 项为非选中内容、第 1 项为选中内容",例如content="['关注', '已关注']"即可实现选中前后文案切换。

CheckTag Events

| 名称 | 参数 | 描述 | | -- | -- | -- | | change |(checked: boolean)| 状态切换时触发 | | click | - | 点击标签时触发 | | close | - | 如果关闭按钮存在,点击关闭按钮时触发 |

其中change事件携带checked: boolean参数,是受控模式下同步选中状态的标准通道。

CheckTag External Classes

| 类名 | 描述 | | -- | -- | | t-class | 根节点样式类 |

源码级实现解析

属性到样式的映射:observers 与 setClass

在 tag.js 中,组件通过observers监听size, shape, theme, variant, closable, disabled六个属性的变化,任一属性变化都会触发setClass(),重新拼装根节点 class:

t-tag 基础类 + t-tag--{theme}(default/primary/warning/danger/success) + t-tag--{variant}(dark/light/outline/light-outline) + t-tag--closable t-is-closable(可关闭时追加) + t-tag--disabled t-is-disabled(禁用时追加) + t-tag--{size}(small/medium/large/extra-large) + t-tag--{shape}(square/round/mark)

这解释了各属性为何以"类名后缀"而非"内联样式"的方式生效:样式文件 tag.wxss 通过.t-tag--small、.t-tag--dark.t-tag--primary、.t-tag--mark等组合选择器命中对应类名,从而形成"尺寸 × 主题 × 变体 × 形状"的矩阵式样式组合。从源码结构看,这种设计让新增一种主题或尺寸只需补充一段 CSS,逻辑层与样式层解耦清晰。

max-width 与图标、关闭按钮的动态计算

maxWidth单独由setTagStyle()处理:当传入数值时自动补px单位(如80→max-width:80px),传字符串时原样使用(如'50px'),最终写入根节点 style。结合 tag.wxss 中.t-tag__text的white-space: nowrap; overflow: hidden; text-overflow: ellipsis,超长文本会在宽度受限后以省略号呈现。

icon与closable的解析依赖公共工具函数calcIcon(见 common/utils.js):布尔值true会套用默认图标名(关闭场景为close),字符串直接作为图标名,对象则视为图标配置透传,从而兼容"关闭按钮 + 默认图标 / 自定义图标 / 自定义插槽"三种形态。对应的 WXML 结构在 tag.wxml 中体现为"前置图标插槽icon+ 文本插槽slot+ 关闭图标(或closable插槽)"的三段式布局,关闭图标上还带有ariaRole: 'button'与ariaLabel: '关闭'的无障碍标注。

虚拟化节点与外部类注入

组件通过wxComponent()装饰器注册(实现在 common/src/instantiationDecorator.js):当运行环境支持虚拟化组件节点时自动开启options.virtualHost = true,并把externalClasses统一扩为['class', ...externalClasses],最终注册进微信Component。这也是custom-style属性存在的意义——在开启虚拟化节点(virtualHost)后,外部无法直接通过组件根节点 class 注入样式,需要改用custom-style向内传递样式。

CSS 变量:可定制样式的设计令牌

组件将全部关键样式参数抽取为 CSS 变量(设计令牌),可在页面或全局样式中覆盖以实现主题定制。下表为组件提供的完整变量清单,默认值中的@xxx为 TDesign 设计体系色板令牌,组件在运行时按"CSS 变量 → 设计令牌 → 具体色值"逐级回退。

| 名称 | 默认值 | 描述 | | -- | -- | -- | | --td-tag-close-icon-color | @font-gray-3 | 关闭图标颜色 | | --td-tag-danger-color | @error-color | danger 主题主色 | | --td-tag-danger-light-color | @error-color-1 | danger 主题浅色 | | --td-tag-default-color | @bg-color-component | default 主题主色 | | --td-tag-default-font-color | @font-gray-1 | default 主题文字色 | | --td-tag-default-light-color | @bg-color-secondarycontainer | default 主题浅色 | | --td-tag-disabled-background-color | @bg-color-component-disabled | 禁用态背景色 | | --td-tag-disabled-border-color | @component-border | 禁用态边框色 | | --td-tag-disabled-color | @font-gray-4 | 禁用态文字色 | | --td-tag-extra-large-font-size | @font-size-base | extra-large 字号 | | --td-tag-extra-large-height | 80rpx | extra-large 高度 | | --td-tag-extra-large-icon-size | 32rpx | extra-large 图标尺寸 | | --td-tag-extra-large-padding | 32rpx - 1px | extra-large 内边距 | | --td-tag-large-font-size | @font-size-base | large 字号 | | --td-tag-large-height | 56rpx | large 高度 | | --td-tag-large-icon-size | 32rpx | large 图标尺寸 | | --td-tag-large-padding | 16rpx - 1px | large 内边距 | | --td-tag-mark-border-radius | @tag-round-border-radius | mark 型圆角 | | --td-tag-medium-font-size | @font-size-s | medium 字号 | | --td-tag-medium-height | 48rpx | medium 高度 | | --td-tag-medium-icon-size | 28rpx | medium 图标尺寸 | | --td-tag-medium-padding | 16rpx - 1px | medium 内边距 | | --td-tag-outline-bg-color | @bg-color-container | outline 变体背景色 | | --td-tag-primary-color | @brand-color | primary 主题主色 | | --td-tag-primary-light-color | @brand-color-light | primary 主题浅色 | | --td-tag-round-border-radius | 999px | round 型圆角 | | --td-tag-small-font-size | @font-size | small 字号 | | --td-tag-small-height | 40rpx | small 高度 | | --td-tag-small-icon-size | 24rpx | small 图标尺寸 | | --td-tag-small-padding | 12rpx - 1px | small 内边距 | | --td-tag-square-border-radius | 8rpx | square 型圆角 | | --td-tag-success-color | @success-color | success 主题主色 | | --td-tag-success-light-color | @success-color-1 | success 主题浅色 | | --td-tag-warning-color | @warning-color | warning 主题主色 |

在 tag.wxss 中可以看到每条规则都写成var(--td-tag-xxx, var(--td-xxx, 具体色值))的多级回退形式,例如 default 主题的描边变体最终回退为#e7e7e7底色、#f3f3f3浅色,primary 主题回退为品牌蓝#0052d9及其浅色#f2f3ff。这意味着即使在完全没有设计令牌注入的环境下,组件也能以稳定的基准色渲染。

覆盖变量的方式十分直接,例如在页面 wxss 中全局调整:

page { --td-tag-primary-color: #07c160; /* 将 primary 主色改为绿色 */ --td-tag-medium-height: 52rpx; /* 调整 medium 尺寸高度 */ --td-tag-round-border-radius: 12rpx; /* 收窄 round 型圆角 */ --td-tag-close-icon-color: #999; /* 调整关闭图标颜色 */ }

实战示例

展示型标签(尺寸 × 主题 × 变体)

<t-tag size="small" theme="primary">小型</t-tag> <t-tag size="medium" theme="success">中号</t-tag> <t-tag size="large" theme="warning">大型</t-tag> <t-tag size="extra-large" theme="danger">超大</t-tag> <t-tag shape="round" theme="default" variant="outline">描边标签</t-tag> <t-tag shape="mark" theme="primary" variant="light">标记型</t-tag>

带图标与最大宽度的标签

<t-tag icon="app" max-width="50px">超长文本会被省略号截断</t-tag>

可关闭标签

<t-tag closable bind:close="onTagClose">可关闭标签</t-tag>
onTagClose() { // 关闭按钮被点击,执行删除/隐藏逻辑 }

可选中标签(非受控 + 受控)

<!-- 非受控:组件内部维护选中态 --> <t-check-tag default-checked="{{false}}" content="{{['未选中', '已选中']}}" bind:change="onChange" /> <!-- 受控:选中态由页面数据驱动 --> <t-check-tag checked="{{checked}}" content="{{['未选中', '已选中']}}" bind:change="onCheckedChange" />
onCheckedChange(e) { this.setData({ checked: e.detail.checked }); }

小结

Tag 与 CheckTag 以"类名矩阵 + CSS 变量令牌 + 事件代理"三个层次完成了展示与交互的完整闭环:属性层通过 observers 驱动类名拼接,样式层通过设计令牌实现多主题、多尺寸的按需定制,事件层则在禁用态守卫下安全抛出。对于需要在微信小程序中快速、统一地表达状态与属性的团队,这套组件既是开箱即用的方案,也是研究小程序组件工程化(虚拟化节点、外部类、插槽、无障碍标注)的优质参考实现。相关源码可继续在 tag 组件目录 及其公共基础 common/src/instantiationDecorator.js、common/utils.js 中深入研读。

  • 示例工程
  • 小程序
  • 前端

【免费下载链接】miniprogram-demo

微信小程序组件 / API / 云开发示例

项目地址:https://gitcode.com/gh_mirrors/mi/miniprogram-demo
点击查看免费下载

相关推荐

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询