☰
TDesign Miniprogram ActionSheet 动作面板完全指南:组件引用、指令调用与宫格分页实现原理
2026/10/14 16:31:21 网站建设 项目流程
  • 前端
  • UI组件
  • 小程序
  • 设计系统
  • 移动开发

【免费下载链接】tdesign-miniprogram

Wechat MiniProgram and Uniapp UI components lib for TDesign

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

本文以packages/components/action-sheet/README.md官方文档为主体,完整讲解 ActionSheet 动作面板在 TDesign Miniprogram 组件库中的引入方式、列表型/宫格型两种主题、指令调用(ActionSheet.show/close)、全套 Props / Events / Slots / CSS Variables API,并结合组件源码还原宫格分页、关闭触发源等底层实现机制,帮助你在小程序中准确落地“底部弹出的一组情境相关操作选项”这一交互模式。

组件概述

ActionSheet 是“由用户操作后触发的一种特定的模态弹出框”,用于呈现一组与当前情境相关的两个或多个选项,典型场景如:长按图片后弹出「保存 / 分享 / 删除」菜单。根据 README 中的说明:

  • 该组件于0.9.0 版本上线,使用时请留意项目依赖的版本;
  • 渲染框架支持情况为WebView(即运行在普通页面,不支持 Skyline)。

从源码结构看,action-sheet.json 声明了它的内部依赖:基于 Popup 组件 承载底部弹出与遮罩,基于 Grid / GridItem 组件 渲染宫格主题,并引用了 Icon 组件 渲染菜单项图标,同时开启了styleIsolation: "apply-shared"样式隔离策略。

引入组件

官方文档提供了全局与局部两种引入方式:

  • 全局引入:在小程序根目录的app.json中配置;
  • 局部引入:在需要使用的页面或组件的index.json中配置。
"usingComponents": { "t-action-sheet": "tdesign-miniprogram/action-sheet/action-sheet", }

配置完成后即可在 WXML 中直接使用<t-action-sheet>标签。

代码演示:列表型、宫格型与组件状态

官方文档的演示分为三组:组件类型(列表型 / 宫格型)、组件状态(宫格型下的失效、自定义色等状态)、组件样式(列表型对齐方式align)。结合 action-sheet.wxml 与 template/grid.wxml 的模板结构,给出可复制运行的完整写法。

列表型动作面板

theme默认值为list,此时模板渲染t-action-sheet__list列表,逐项绑定tap事件并支持icon/suffixIcon/description/color/disabled:

<view class="container"> <t-button block theme="light" bindtap="showActionSheet">打开列表型动作面板</t-button> <t-action-sheet id="t-action-sheet" visible="{{ visible }}" theme="list" description="这是一段描述文字" cancel-text="取消" items="{{ items }}" bind:visible-change="onVisibleChange" bind:selected="onSelect" bind:cancel="onCancel" /> </view>
Page({ data: { visible: false, items: [ { label: '默认选项' }, { label: '带描述选项', description: '选项的补充说明' }, { label: '失效选项', disabled: true }, { label: '警告选项', color: '#e34d59' }, { label: '带图标选项', icon: 'photo' }, ], }, showActionSheet() { this.setData({ visible: true }); }, onVisibleChange(e) { this.setData({ visible: e.detail.visible }); }, onSelect(e) { console.log('选中项', e.detail.selected, e.detail.index); }, onCancel() { console.log('点击取消'); }, });

宫格型动作面板

设置theme="grid"后,模板切换为宫格渲染。此时count属性生效(默认8,即每页 8 项),菜单项按每页count个进行分页;单页直接渲染t-grid,多页则自动包裹在swiper中并附带底部圆点指示器(见 template/grid.wxml 中gridThemeItems.length === 1与> 1两个分支):

<t-action-sheet id="t-action-sheet" visible="{{ visible }}" theme="grid" count="{{ 8 }}" items="{{ gridItems }}" bind:selected="onSelect" />
data: { gridItems: [ { label: '自定义选项', color: '#0052D9', icon: 'edit' }, { label: '文字', icon: 'image' }, { label: '失效选项', disabled: true }, // ... 超过 count 数量的项会自动分页 ], },

这一分页行为在源码中有直接对应:action-sheet.ts 中的splitGridThemeActions方法在非 grid 主题时直接返回,grid 主题下调用 chunk 工具函数 把items按count切片为gridThemeItems,items的 observer 会在数据变化时重新分片。

组件状态与对齐方式

  • 状态:items中的disabled项展示失效样式且点击不会触发关闭;color字段通过行内样式为单个菜单项着色(action-sheet.wxml 第 29 行);
  • 对齐:align可取center(默认)或left,后者会让描述文字与列表项内容左对齐(action-sheet.less 中.t-action-sheet--left的样式规则)。
<t-action-sheet visible="{{ visible }}" align="left" description="左对齐" items="{{ items }}" />

支持指令调用

除了常规的visible属性受控引用,ActionSheet 还支持指令式调用,无需手动管理visible。文档给出的用法为:

import ActionSheet, { ActionSheetTheme } from 'tdesign-miniprogram/action-sheet/index'; // 指令调用不同于组件引用不需要传入visible const basicListOption: ActionSheetShowOption = { theme: ActionSheetTheme.List, selector: '#t-action-sheet', items: [ { label: '默认选项', }, { label: '失效选项', disabled: true, }, { label: '警告选项', color: '#e34d59', }, ], }; const handler = ActionSheet.show(basicListOption);

指令调用的关闭如下:

handler.close();

指令调用的完整入口在 index.ts 中,它把 show.ts 中的show/close函数包装为默认导出对象,并同时导出ActionSheetItem、ActionSheetShowOption类型与ActionSheetTheme枚举(List = 'list'、Grid = 'grid')。ActionSheetShowOption由组件属性(剔除visible)扩展出context(页面/组件实例)与selector(默认#t-action-sheet)两个字段(show.ts)。

从源码结构看,指令调用有几点值得注意的实现细节:

  1. 实例定位:show内部通过 getInstance 按context+selector查找组件实例;未传context时默认取当前栈顶页面,找不到实例会在控制台打印「未找到组件,请确认 selector && context 是否正确」;
  2. autoClose 机制:action-sheet.ts 中show(options)会把实例初始化时的属性快照(initialData)与本次传入的options合并后setData,并将visible置为true、标记autoClose = true。此后无论是点击遮罩(onPopupVisibleChange)还是点击取消按钮(onCancel),都会自动把visible收回为false,实现“一次 show、自动关闭”的指令语义;
  3. 关闭来源:指令式close()会以trigger: 'command'触发close事件,与遮罩点击的trigger: 'overlay'、选中项目的trigger: 'select'相区分,方便业务侧埋点区分关闭路径。

官方单元测试test/index.test.js 中的instance: props用例完整覆盖了该链路:mockgetInstance后依次调用show→ 模拟点击遮罩 → 无参show()/close()(验证容错)→ 带selector与context的close,并断言visible-change事件按预期次数触发、最终visible为false。

API

ActionSheet Props

| 名称 | 类型 | 默认值 | 描述 | 必传 | |-- | -- | -- | -- | -- | | style | Object | - | 样式 | N | | custom-style | Object | - | 样式,一般用于开启虚拟化组件节点场景 | N | | align | String | center |0.29.0新增。水平对齐方式。可选项:center/left | N | | cancel-text | String | - | 设置取消按钮的文本(未传时回退到全局语言的“取消”文案) | N | | count | Number | 8 | 设置每页展示菜单的数量,仅当 theme=grid 时有效 | N | | description | String | - |0.29.0新增。动作面板描述文字 | N | | items | Array | - | 必需。菜单项。TS 类型:Array<string \| ActionSheetItem>,interface ActionSheetItem { label: string; description?: string; color?: string; disabled?: boolean; icon?: string \| object; suffixIcon?: string \| object }。详细类型定义 | Y | | popup-props | Object | {} | 透传 Popup 组件全部属性。TS 类型:PopupProps,详见 Popup API | N | | show-cancel | Boolean | true | 是否显示取消按钮 | N | | show-overlay | Boolean | true | 是否显示遮罩层 | N | | theme | String | list | 展示类型,列表和表格形式展示。可选项:list/grid | N | | using-custom-navbar | Boolean | false | 是否使用了自定义导航栏 | N | | visible | Boolean | false | 显示与隐藏(受控属性) | N | | default-visible | Boolean | undefined | 显示与隐藏。非受控属性 | N |

几点源码级补充:

  • 默认值的权威来源是自动生成的 props.ts,与上表一一对应;type.ts 中则给出了TdActionSheetProps的完整 TypeScript 声明,可用于业务侧 TS 类型约束;
  • visible是受控属性:action-sheet.ts 中通过controlledProps声明了{ key: 'visible', event: 'visible-change' }的受控契约,组件自身在内部关闭时只会派发visible-change事件,需要业务侧回写visible才能完成状态闭环;default-visible则对应非受控用法;
  • style/custom-style会合并应用到根节点(action-sheet.wxml 中_. _style([style, customStyle])),开启虚拟 host(virtualHost)的页面建议用custom-style传递样式;
  • 取消按钮文案回退:WXML 中为{{ cancelText || globalConfig.cancel }},即未设置cancel-text时取全局语言配置,locale/zh_CN.ts 中actionSheet.cancel默认为「取消」。

ActionSheet Events

| 名称 | 参数 | 描述 | |-- | -- | -- | | cancel | - | 点击取消按钮时触发 | | close |(trigger: ActionSheetTriggerSource)| 关闭时触发。type ActionSheetTriggerSource = 'overlay' \| 'command' \| 'select',详细类型定义 | | selected |(selected: ActionSheetItem \| string, index: number)| 选择菜单项时触发 |

此外还有受控事件visible-change(参数{ visible: boolean }),由受控属性契约驱动,用于感知面板显隐变化并回写visible。

close事件的三种trigger取值分别对应三条源码路径:遮罩点击 → onPopupVisibleChange('overlay')、选中项 → onSelect('select',且仅当项未disabled时才触发关闭)、指令关闭 →close()方法('command')。

ActionSheet Slots

| 名称 | 描述 | |-- | -- | | - | 默认插槽,自定义内容区域内容 |

默认插槽位于内容区与取消按钮之间(action-sheet.wxml 中t-popup内的<slot />),可用于在菜单下方追加自定义区块,例如「投诉建议」入口。

ActionSheet External Classes

类名 | 描述 |-- | -- |t-class | 根节点样式类 |t-class-cancel | 取消样式类 |t-class-content | 内容样式类

三个外部样式类在 action-sheet.ts 的externalClasses中声明,并分别挂载到根节点、取消按钮与内容容器上,用于在不修改组件样式的前提下从使用方注入类名。

CSS Variables

组件提供了下列 CSS 变量,可用于自定义样式(默认值来源于 action-sheet.less 中的 Less 变量回退):

| 名称 | 默认值 | 描述 | |-- | -- | -- | | --td-action-sheet-border-color | @component-stroke | 分隔线颜色 | | --td-action-sheet-border-radius | @radius-extraLarge | 内容区顶部圆角 | | --td-action-sheet-cancel-color | @text-color-primary | 取消按钮文字颜色 | | --td-action-sheet-color | @text-color-primary | 菜单项文字颜色 | | --td-action-sheet-description-color | @text-color-placeholder | 描述/辅助文字颜色 | | --td-action-sheet-description-font | @font-body-medium | 描述文字字体 | | --td-action-sheet-disabled-color | @text-color-disabled | 失效项文字颜色 | | --td-action-sheet-dot-active-color | @brand-color | 宫格分页圆点选中色 | | --td-action-sheet-dot-color | @text-color-disabled | 宫格分页圆点默认色 | | --td-action-sheet-dot-size | 16rpx | 宫格分页圆点尺寸 | | --td-action-sheet-gap-color | @bg-color-page | 取消区与内容区分隔条颜色 |

实现细节与常见问题

宫格模式下的选中索引如何计算?onSelect 中,宫格模式取gridThemeItems[currentSwiperIndex][index],并计算真实索引realIndex = index + currentSwiperIndex * count,保证selected事件回传的index始终是原始items数组中的下标,而不是分页后的局部下标;currentSwiperIndex由swiper的bindchange(onSwiperChange)同步。

图标属性如何解析?items中的icon/suffixIcon支持字符串(图标名)或对象两种形式,action-sheet.wxs 中的getIconData在模板层完成归一化:字符串转为{ name: icon },非空对象原样透传,其余情况返回null(不渲染图标)。

列表项与宫格项的差异?列表型额外渲染suffixIcon(行尾图标)与description(项下方说明文字);宫格型则把label/icon/description交给t-grid-item渲染,并通过--td-grid-item-text-color变量透传项级color(见 template/grid.wxml)。

遮罩层与层级控制:show-overlay透传给t-popup控制遮罩显隐,popup-props可透传 Popup 的全部属性(如zIndex、overlayProps),见 action-sheet.wxml 中z-index与overlay-props的绑定方式。

参考

  • 组件文档:packages/components/action-sheet/README.md
  • 组件实现:action-sheet.ts、action-sheet.wxml、template/grid.wxml
  • 指令调用:show.ts、index.ts
  • 类型与默认值:type.ts、props.ts
  • 样式实现:action-sheet.less
  • 单元测试:test/index.test.js
  • 前端
  • UI组件
  • 小程序
  • 设计系统
  • 移动开发

【免费下载链接】tdesign-miniprogram

Wechat MiniProgram and Uniapp UI components lib for TDesign

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

相关推荐

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

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

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

立即咨询