- 前端
- UI组件
- 小程序
- 设计系统
- 移动开发
【免费下载链接】tdesign-miniprogram
Wechat MiniProgram and Uniapp UI components lib for TDesign
本文以 Segmented 分段控制器官方文档 为核心,结合组件源码、示例与测试,系统讲解 tdesign-miniprogram 中分段控制器的接入方式、数据化配置、禁用态、事件回调以及底层实现原理。读完本文,你将能在微信小程序中熟练配置
t-segmented,理解其"滑块动画"的实现机制,并能通过 External Classes 与 CSS Variables 完成深度定制。
组件概览:面向单选的轻量控制器
Segmented 分段控制器用于展示多个选项并允许用户选择其中单个选项,是典型的单选项切换组件。根据 官方文档,该组件于1.14.0 版本上线,使用前需要留意项目所依赖的 tdesign-miniprogram 版本;渲染框架方面同时支持Skyline 与 WebView两种渲染方式,并且仓库中已提供 Skyline 渲染示例,可在 Skyline 页面中直接复用。
快速接入:全局与局部引入
分段控制器属于页面级组件,接入方式与其他 tdesign-miniprogram 组件一致,支持两种引入方式(详见 README 引入章节):
- 全局引入:在小程序根目录
app.json的usingComponents中注册,全项目可用; - 局部引入:在需要使用组件的页面或组件自身的
index.json中注册。
配置示例如下:
{ "usingComponents": { "t-segmented": "tdesign-miniprogram/segmented/segmented" } }接入后即可在 WXML 中直接使用,例如:
<t-segmented options="{{options}}" default-value="{{0}}" />组件自身声明为独立 Component,其 segmented.json 中设置了"styleIsolation": "apply-shared",并内部依赖t-icon(icon 组件)以支持带图标选项的渲染。
数据化配置:options 与类型定义
分段控制器的选项全部通过options属性数据化配置,官方类型为string[] | number[] | SegmentedItem[],其中:
interface SegmentedItem { value: string | number; // 选项值,change 事件回调中返回 label?: string; // 展示文案,缺省时使用 value 的字符串形式 icon?: string | object; // 选项图标,支持图标名或图标配置对象 disabled?: boolean; // 单个选项是否禁用 }完整类型定义见 type.ts。
从 segmented.ts 源码 可以看到,组件在options变化时通过updateOptions做归一化处理:
- 当传入的选项是纯
string/number时,自动包装为{ value: option, label: String(option) },因此你可以直接写options="{{['选项A', '选项B']}}"; - 当传入
SegmentedItem对象时,label缺省回退为String(option.value); - 图标通过公共工具 calcIcon 归一化:字符串图标名被转换为
{ name }对象,对象图标原样透传,最终交给 icon 模板 渲染。
基础用法
对应 base 示例,传入选项对象数组并配合bind:change:
Component({ data: { options: [ { value: 0, label: '选项' }, { value: 1, label: '选项' }, { value: 2, label: '选项' }, ], }, });<t-segmented options="{{options}}" default-value="{{0}}" />若需要图标,可在SegmentedItem中声明icon:
optionsWithIcon: [ { value: 0, label: '选项', icon: 'home' }, { value: 1, label: '选项', icon: 'home' }, { value: 2, label: '选项', icon: 'home' }, ],自适应宽度(block)
设置block属性后,控制器将撑满父元素宽度,选项在内部等分铺开。对应 block 示例:
<t-segmented block options="{{options}}" default-value="{{0}}" />从 segmented.less 可见,block模式下根节点切换为display: flex; width: 100%,每个选项设置flex: 1; min-width: 0,并将选项内文案做ellipsis溢出省略,保证窄屏下的可用性。非block模式则保持inline-block自适应内容宽度。
组件状态:禁用态控制
禁用态分为整体禁用与单项禁用两个层级(对应 disabled 示例):
- 整体禁用:设置
disabled属性,整个控制器不可交互; - 单项禁用:在
SegmentedItem中给某个选项设置disabled: true,仅该选项不可点击。
optionsWithDisabled: [ { value: 0, label: '选中' }, { value: 1, label: '默认' }, { value: 2, label: '禁用', disabled: true }, ],<t-segmented options="{{optionsWithDisabled}}" value="{{valueWithDisabled}}" bind:change="onChangeWithDisabled" />点击拦截逻辑在源码 handleSelect 中体现:if (disabled || !item || item.disabled) return;同时校验组件级disabled与选项级item.disabled;样式上,禁用项在 segmented.less 中通过pointer-events: none与text-color-disabled颜色呈现。
Props 总览与默认值
根据 README API 章节 与 props.ts,完整属性如下:
| 名称 | 类型 | 默认值 | 说明 | | -- | -- | -- | -- | | style | Object | - | 样式 | | custom-style | Object | - | 样式,一般用于开启虚拟化组件节点场景 | | block | Boolean | false | 是否撑满父元素宽度 | | disabled | Boolean | - | 是否禁用 | | options | Object | [] | 数据化配置选项内容,支持string[] \| number[] \| SegmentedItem[]| | value | String / Number | - | 当前选中的值(受控) | | default-value | String / Number | undefined | 当前选中的值(非受控属性) |
其中value默认值为null(见 props.ts),组件内部用它和defaultValue区分受控/非受控两种模式。
事件与受控/非受控机制
组件仅对外暴露一个事件:
| 名称 | 参数 | 描述 | | -- | -- | -- | | change |(detail: { value: string \| number, selectedOption: SegmentedItem })| 选项值发生变化时触发 |
selectedOption返回的是原始 options 数组中对应的那个选项,方便拿到label、icon等附加信息。
在 segmented.ts 中,组件通过controlledProps声明了受控关系:
controlledProps = [ { key: 'value', event: 'change' }, ];这意味着:
- 使用
value+bind:change时是受控用法,开发者需要在 change 回调里setData({ value: e.detail.value }),选中态完全由外部数据驱动; - 使用
default-value时是非受控用法,组件内部维护选中状态,不需要手动更新。
对应示例见 base 示例的 change 回调:
onChangeWithIcon(e) { console.log('onChangeWithIcon:', e.detail); this.setData({ valueWithIcon: e.detail.value }); }源码原理:滑块动画(thumb)是怎么算出来的
分段控制器的视觉核心是选中项底部的滑动背景块(thumb)。其实现思路在 segmented.wxml 与 segmented.ts 中非常清晰:
- 根节点内先渲染一个绝对定位的
thumb视图(class 为{{classPrefix}}__thumb,同时挂载t-class-thumb外部样式类),再渲染选项列表; options或value变化时,通过updateActiveIndex用segmentItems.findIndex((item) => item.value === value)找到当前激活项下标activeIndex;updateThumb使用公共工具 getRect(底层是createSelectorQuery().boundingClientRect())并行测量"当前激活项"和"选项组容器"的矩形,计算出滑块应平移的距离:
const left = itemRect.left - groupRect.left; this.setData({ thumbStyle: `width: ${itemRect.width}px; transform: translateX(${left}px);`, });- 动画过渡由 CSS 完成:segmented.less 中 thumb 声明了
transition: @segmented-transition与will-change: transform, width,切换选项时滑块便平滑滑动到新位置。
值得注意的边界行为:当value为null(未选中任何项)时,activeIndex保持-1,updateThumb直接 return,此时不渲染滑块背景。
深度定制:External Classes 与 CSS Variables
External Classes
组件在源码中声明了三个外部样式类(segmented.ts):
| 类名 | 描述 | | -- | -- | | t-class | 根节点样式类 | | t-class-item | 列表子项样式类 | | t-class-thumb | 动画背景样式类 |
使用时在页面 JSON 中配置styleIsolation为isolated(或apply-shared)后,通过externalClasses传入即可覆盖对应节点的样式,例如调整滑块圆角或选项内边距。
CSS Variables
组件通过 segmented.less 暴露了 7 个 CSS 变量,用于在外部统一改主题(变量默认值取自 tdesign 设计令牌):
| 变量名 | 默认值 | | -- | -- | | --td-segmented-bg-color | @bg-color-component-disabled | | --td-segmented-item-active-bg | @bg-color-container | | --td-segmented-item-active-color | @brand-color | | --td-segmented-item-color | @text-color-primary | | --td-segmented-item-disabled-color | @text-color-disabled | | --td-segmented-item-label-font | @font-body-medium | | --td-segmented-transition | all @anim-duration-base @anim-time-fn-easing |
以 less 源码 为例,变量采用"var + 兜底令牌"的写法:
@segmented-item-active-color: var(--td-segmented-item-active-color, @brand-color);因此你可以直接在页面 wxss 中覆盖这些变量来整体换肤,例如:
page { --td-segmented-item-active-color: #ff6b00; --td-segmented-item-label-font: 16px; }测试与验证
仓库为 Segmented 提供了基于miniprogram-simulate的 demo 测试:测试会依次加载base、block、disabled三个示例页面并做快照断言,覆盖了基础选项、自适应宽度与禁用态三种典型场景。如果你修改了组件或示例,可运行npm run test:demo重新生成快照(该文件由脚本自动生成,见文件头注释,手写修改会被覆盖)。
小结
Segmented 分段控制器是 tdesign-miniprogram 中用于单选场景的轻量组件:通过options数据化配置即可快速生成选项,支持字符串/数字/对象三种选项形态、整体与单项两级禁用、受控与非受控两种取值模式,其滑块动画基于getRect测量加 CSS transition 实现,并通过 External Classes 与 CSS Variables 提供了灵活的样式扩展点。接入、配置与深度定制的完整示例均可直接参考仓库中的 _example 目录,其中还包含了 Skyline 渲染示例 供对应渲染框架下使用。
- 前端
- UI组件
- 小程序
- 设计系统
- 移动开发
【免费下载链接】tdesign-miniprogram
Wechat MiniProgram and Uniapp UI components lib for TDesign
相关推荐
TDesign Miniprogram Segmented 分段控制器:API 详解与实现原理
TDesign Miniprogram Segmented 分段控制器:API 详解与实现原理 Segmented(分段控制器)是 TDesign Minipr
前端UI组件小程序设计系统移动开发ng-zorro-antd Segmented 分段控制器入门:从零上手基本用法与源码级原理解析
ng zorro antd Segmented 分段控制器入门:从零上手基本用法与源码级原理解析 本文以 ng zorro antd 的 nz segmente
UI组件前端ant-design-blazor Segmented 分段控制器组件完全指南:从基本用法到源码原理
ant design blazor Segmented 分段控制器组件完全指南:从基本用法到源码原理 分段控制器(Segmented)是 ant design
前端UI组件设计系统
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考