Skip to content

n-action-sheet 动作面板 ​

底部弹出的操作菜单:普通操作列表(纵向)与分享面板(layout="share",每行横向、可滚动)共用同一套数据解析、选择守卫与事件出口。弹层骨架(遮罩 / 滑入滑出 / 把手拖拽 / 底部安全区)内嵌 n-popup 承担,本组件只给动作内容:标题与说明、逐项文字 / 说明 / 颜色 / 禁用 / 加载、取消与关闭入口、字符串与对象混合数据、微信开放能力按项承接。

  1. 受控显隐:visible 置 true 弹出;取消 / 关闭 / 选中自动收起 / 遮罩 / 拖拽 / Web Escape 只派发语义事件并同帧回传 update:visible(false)——组件不自行收起,在回调里把 visible 改回 false 即完成闭环;父组件不回写时面板保持打开并恢复可操作(不产生隐式内部收起)
  2. 数据三种结构(一次输入必须为一种):字符串一维(快捷写法)、对象一维、对象二维(share 布局按行横向排列)。结构混装、缺文字、字段类型错误、重复 id 走 dataError 错误态:动作区显示占位说明、保留取消 / 关闭,不再渲染旧数据
  3. close 事件的含义是「请求收起」,参数区分来源(select / cancel / close / mask / drag / escape)——它不是退场动画完成事件;取消路径另有 cancel(来源) 与之同帧同发
  4. 禁用 / 加载项做真实拦截:保色相降透明,点击与原生能力均不可用;不绑定原生 disabled
  5. 微信开放能力按项配置(对象项 openType 及配套参数):能力项选中只派发 select,原生回调按原生名事件转发,是否收起由业务在回调里决定——auto-close 对能力项不生效,避免抢先销毁授权按钮
  6. 高度自适应:短内容自然高度;超出 min(期望高度, 窗口 80%) 时实测三段高度,头部文本与内容区分别压进滚动视口,取消 / 关闭始终可达

平台兼容性 ​

App H5 微信小程序 支付宝小程序 百度小程序 头条小程序 QQ小程序
√ √ √ × × × ×

微信开放能力(open-type 及其参数、回调事件)仅微信小程序端生效;其它端 openType 只是普通数据,选项按普通业务项处理。

API ​

属性 ​

参数 说明 类型 默认值 可选值
visible 显隐开关(受控模式:取消/关闭/选中自动收起/遮罩/拖拽只派发语义事件并回传 update:visible(false),收起由使用者改回 false) Boolean false -
items 动作数据:字符串一维 / 对象一维 / 对象二维;一次输入必须为一种结构,混合形状走 dataError 错误态 Array [] -
text-key 对象项主文字字段名(空串按 "text");只映射主文字,其余字段名固定 String "text" -
title 面板标题(空串不占标题空间;替代文本区用 #header 插槽) String "" -
description 面板整体说明(标题下方的次要文字,空串不占位) String "" -
layout 布局:list = 纵向动作列表;share = 分享面板(每行横向、可滚动) String "list" list / share
columns share 每行可视列数;正整数按实际行宽等分,超出横向滚动;0 沿用主题项宽。正值时忽略 align,不足一行从首列对齐 Number 0 ≥0 的整数
variant 外观:card 独立圆角卡片;line 连续表面,列表内部细分割线,取消区用背景留白分组;不改变交互 String "card" card / line
align share 行内排列:between 在整行放得下时分散到两端(单项居中),放不下回到 start 可滚动 String "start" start / between
show-cancel 显示底部取消入口 Boolean true -
cancel-text 取消按钮文案(空串取内置多语言文案;隐藏取消入口用 show-cancel) String "" -
show-close 标题区右侧关闭按钮(点击等同取消:cancel("close") + 建议收起) Boolean false -
auto-close 可用普通项选中后自动请求收起;异步业务推荐 false。微信能力项不受本项影响 Boolean true -
mask-closable 点击面板外遮罩请求取消并收起;置 false 时遮罩与 Web Escape 不再触发关闭,取消/关闭按钮仍可用 Boolean true -
show-handle 底部把手小条(透传 n-popup) Boolean false -
drag-close 允许头部下拉关闭;复用已有把手与标题区,无头部内容时保留 20px 拖拽区,列表/分享区不参与拖拽 Boolean false -
safe-area-inset-bottom 底部安全区垫层(由 n-popup 自动读取) Boolean true -
duration 出入场过渡时长(毫秒):0 = 即显模式 Number 300 -
z-index 弹层层级:0 = 跟随内置默认(1000);大于 0 写入根节点行内 z-index Number 0 -
height 整个面板的期望高度(px,含标题/列表/取消/安全区):0 = 随内容自适应;超过窗口 80% 按 80% 封顶 Number 0 -
max-width 面板最大宽度(px):实际宽度 = min(窗口宽, max-width),宽屏底部水平居中 Number 560 -
radius 顶部圆角(px):-1 取主题令牌,0 直角 Number -1 -
mask-color 遮罩颜色(非空仅覆盖本实例) String "" 与 css 相同
panel-style n-popup 面板行内样式(如表面色);不得覆盖其 transform/transition String "" 与 css 相同
title-style 默认标题文字的行内样式 String "" 与 css 相同
description-style 默认整体说明文字的行内样式 String "" 与 css 相同
item-style 每个动作项内容容器的行内样式(不能绕过禁用/加载守卫) String "" 与 css 相同
text-style 默认项主文字的行内样式 String "" 与 css 相同
item-description-style 默认逐项说明文字的行内样式 String "" 与 css 相同
icon-style 图标插槽宿主盒的行内样式(底色、圆角等) String "" 与 css 相同
cancel-style 取消按钮容器的行内样式 String "" 与 css 相同
custom-class 挂到弹层根节点的额外 class(类须在组件样式表内定义) String "" -
custom-style 弹层根节点行内样式(z-index 正值优先用 z-index prop) String "" 与 css 相同

事件 ​

事件名 说明 回调参数
select 可用项激活时触发一次(含微信能力项);不表示异步业务成功或授权成功 { row, index, item }:原始位置 + 原始业务对象
cancel 取消按钮 / 关闭按钮 / 可关闭遮罩 / 头部拖拽 / Web Escape 请求放弃时触发 String(来源:cancel/close/mask/drag/escape)
close 组件请求收起的来源信号,与 cancel 同帧同发;注意这是「请求收起」,不是退场动画完成事件 String(来源:select/cancel/close/mask/drag/escape)
update:visible 关闭建议(false):配合 :visible 手动双向控制显隐 Boolean
dataError 数据 / 配置校验错误;按错误签名变化派发一次
getuserinfo open-type=getUserInfo 回调(微信小程序) { row, index, item, event }:点击时上下文 + 原生事件
contact open-type=contact 客服会话回调(微信小程序)
getphonenumber open-type=getPhoneNumber 回调(微信小程序)
getrealtimephonenumber open-type=getRealtimePhoneNumber 回调(微信小程序)
error 微信开放能力错误原样透传(与 dataError 数据校验错误无关)
opensetting open-type=openSetting 授权页关闭后回调(微信小程序)
launchapp open-type=launchApp 唤起 APP 回调(微信小程序)
chooseavatar open-type=chooseAvatar 回调(微信小程序)
agreeprivacyauthorization 用户同意隐私协议回调(微信小程序)
createliveactivity open-type=liveActivity 订阅回调(微信小程序)

插槽 ​

插槽名 说明
header 替代标题 + 说明文本区(把手与关闭按钮仍由组件管理)
prepend 头部之后、动作数据区之前的补充内容(随内容区滚动)
icon 默认项中的图标内容(只替换图标盒,不拥有点击守卫);参数 { item, row, index };list 图标在文字左、share 在文字上;未提供不留空位
item 替代单项内容(交互宿主、原生能力、禁用与加载守卫保留);参数 { item, row, index, disabled, loading };不要放入需要独立点击的控件
append 动作区之后、取消区之前的补充内容(随内容区滚动)
footer 替代默认取消区(组件不解析插槽内部按钮,调用方自行设置 visible=false)

主题与样式隔离 ​

页面 class 打不进组件内部。定制通道按优先级:

  1. 主题令牌:--n-action-sheet-* 运行时变量或 uni.scss 覆盖同名 $n-action-sheet-*
  2. 根节点 custom-class / custom-style;面板本体走 panel-style
  3. 内部节点行内样式 prop(title-style / text-style / icon-style 等)
令牌 默认值 含义
--n-action-sheet-radius 16px 顶部圆角
--n-action-sheet-padding-x 10px 默认内容左右内距
--n-action-sheet-title-size 16px 标题字号
--n-action-sheet-description-size 14px 整体说明字号
--n-action-sheet-text-size 14px 列表主文字字号
--n-action-sheet-item-description-size 13px 逐项说明字号
--n-action-sheet-share-text-size 13px 分享标签字号
--n-action-sheet-item-min-height 44px card 列表项最小高度
--n-action-sheet-cancel-min-height 44px card 取消按钮最小高度
--n-action-sheet-cancel-size 14px 取消文字字号
--n-action-sheet-cancel-gap 10px card 外观取消区与菜单的背景间隔
--n-action-sheet-line-cancel-gap 8px line 外观取消区与菜单的背景间隔
--n-action-sheet-line-min-height 48px line 列表项与取消按钮最小高度
--n-action-sheet-line-padding-x 0px line 列表内容左右内距与分割线两端留白
--n-action-sheet-drag-area-height 20px drag-close 开启且没有把手、标题、说明、header 插槽与关闭按钮时的顶部拖拽区高度
--n-action-sheet-divider-width 0.5px line 列表内部细分割线高度
--n-action-sheet-divider-color var(--n-border, #e5e6eb) line 列表内部细分割线颜色
--n-action-sheet-share-icon-size 40px 分享图标盒尺寸
--n-action-sheet-share-item-width 76px 分享项定宽
--n-action-sheet-share-row-gap 4px 分享行距
--n-action-sheet-icon-text-gap 4px 图标与文字间距
--n-action-sheet-disabled-opacity 0.4 禁用透明度
--n-action-sheet-active-opacity 0.7 按压透明度
--n-action-sheet-icon-background transparent 图标盒底色

文字、表面、分隔线等中性色直接引用全局令牌(--n-text-1 / --n-text-2 / --n-bg-1 / --n-bg-2 / --n-border),随深浅主题自动切换;遮罩复用 --n-popup-mask-color(mask-color prop 覆盖本实例)。

长内容与布局限制 ​

  • 面板高度上限为窗口高度的 80%(height prop 期望值与之取小);超限后内容区为滚动视口,头部文本超长时同样压进头部滚动区,取消 / 关闭始终可达
  • header / footer 插槽自定义内容须自行控制高度:固定区过高会压缩内容区(内容区最低保 120px,实在放不下时以可操作最小高度为准)
  • share 行内 align="between" 需实测行内容宽度:放得下分散到两端(单项居中),放不下自动回到 start 可滚动,不做假列数切换
  • 面板宽度 min(窗口宽, max-width),宽屏底部水平居中;小屏满宽

实现说明 ​

  • 分享布局保留主题项宽与横向滚动;columns 为正整数时按实测动作区宽度与主题留白等分可视列,替代调用者计算窗口宽度和硬编码边距。末行从首列起对齐,窗口与面板宽度变化自动重算。

  • 外观与布局分离:variant="card" 保留独立圆角和项间距;variant="line" 列表与分割线左右铺满、仅非末项显示细线,列表项与取消按钮最小高度均为 48px,取消区前保留 8px 背景间隔。两种外观共享数据、禁用、加载和事件逻辑,share 始终保留横向图标布局。运行中切换外观只更新样式与分割线显隐,保留插槽和能力承接节点;默认 card 保持现有用法。

  • 弹层骨架零重复:n-popup 是唯一弹层宿主(direction="bottom"、空档位),本组件不复刻遮罩、过渡、拖拽与安全区;n-popup 的 close(reason) 是唯一关闭来源通道,组件统一转换为 cancel + close + update:visible 出口

  • 数据边界:输入经显式类型校验后归一为强类型渲染模型;不修改业务数组与对象,不注入内部字段;字符串项的事件 item 是 { [textKey]: 原字符串 } 归一对象,对象项回传原引用

  • 能力回调归因:点击时对 item / row / index 与会话标识做快照,原生回调按快照归因并即取即删——列表重排、项删除、面板关闭重开后到达的迟到回调一律作废,不会归到新项或新会话

  • 能力承接层:透明空 button 覆盖整项(button 是叶子节点不可嵌内容),禁用 / 加载时只清空 open-type、不销毁节点——已启动回调的接收节点稳定,等待期间不重复启动能力

  • 高度策略:打开时以 selectorQuery 实测头部 / 内容 / 底部三段自然高再分配滚动视口(无项数 × 定高的估算);间距全部内收为各段自身 padding,实测无需常量补偿;窗口变化(旋转 / 分屏)自动重测

  • 重建边界:只有结构位翻转(布局互换、加载圈出现、行结构变化、项身份更替)整根重建;文字 / 颜色 / 禁用等纯属性变化原地更新,插槽内部状态与横向滚动位置不受无关更新影响

已知限制 ​

  • Web 端焦点圈定、入口恢复、最上层键盘所有权与背景隔离由 n-popup 统一管理;逻辑回归已通过,辅助功能朗读仍需真机验证
  • 拖拽关闭开启时,头部(把手 + 标题区)是拖拽手势区,头部内长文本的触摸滚动让位于拖拽;需要头部滚动的场景关闭 drag-close
  • 微信 share / feedback 等能力无完成回调,组件不会自动收起,结果由页面原生流程接管
  • 尚未完成的验收项见工作区验收记录文档(真机微信能力回调、系统最大字体、安全区机型等)

记录 · 思考 · 创作