Skip to content

n-modal 模态对话框 ​

居中弹出的对话框:标题 + 正文 + 操作按钮(确认 / 取消),用于重要操作的二次确认、关键信息提示等需要中断用户流程的场景。弹层骨架(遮罩 / 居中面板 / 出入场缩放淡入过渡 / 遮罩点击关闭)内嵌 n-popup(direction="center")承担,本组件只给对话框内容。

  1. 受控显隐:visible 置 true 弹出;点确认按钮派发 confirm、点取消 / 关闭按钮 / 遮罩(mask-closable 开启时)派发 cancel——两类按钮点击均同帧回传 update:visible(false) 建议收起,最终收起由使用者把 visible 改回 false;遮罩点击额外先派发 close(单指遮罩来源,便于与按钮关闭区分)
  2. 文案优先级:header / default / footer 三插槽分别优先于 title / content / 默认按钮;按钮文案空串时取内置多语言(确认 = "确定"、取消 = "取消")
  3. 按钮类型:confirm-type / cancel-type 取 primary / success / warning / error / info 时为功能色填充、文字白色;取 default 时为中性灰底、文字墨色——确认默认 primary(强调主操作)、取消默认 default(弱化次操作);文本形态(button-model="text")为主次胶囊:功能色钮实心胶囊白字、default 型幽灵灰字
  4. 按钮组两种来源:默认确认 / 取消两钮,或 buttons 数组整组替换(任意数量、每钮独立文案 / 类型 / 禁用)——后者点击只派发 button-click(回传数组下标),不派发 confirm / cancel、不回传 update:visible,是否收起由使用者按业务决定
  5. 排布与形态:button-direction="column" 竖排满宽(系统弹窗 / 长文案多钮常用);button-reverse 反转顺序(确认左置);button-model="text" 主次胶囊形态(功能色钮实心胶囊、default 型幽灵文字;横排并排 / 竖排堆叠)
  6. 异步提交:confirm-loading 置 true 时确认钮显示旋转加载圈并拦截重复点击,完成后置 false 再收起;top 负值上移面板避让视线中心;z-index 大于 0 时写根节点行内层级(多弹层叠加避让)
  7. 关闭按钮(show-close)是标题栏右侧的纯 CSS 自绘 ×(无字体依赖),点击等同取消
  8. 出入场为缩放 + 淡入淡出过渡(n-popup center 方向,时长由 duration prop 控制,0 = 即显)

平台兼容性 ​

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

API ​

属性 ​

参数 说明 类型 默认值 可选值
visible 显隐开关(受控模式:按钮点击 / 遮罩点击只派发 confirm / cancel 并回传 update:visible(false),收起由使用者改回 false) Boolean false -
title 标题文案(空串 = 不渲染标题文本,留结构给 header 插槽或仅显关闭按钮;无关闭钮时标题居中,有关闭钮时左对齐) String "" -
content 正文文案(默认插槽提供内容时失效) String "" -
confirm-text 确认按钮文案(空串 = 取内置多语言文案) String "" -
cancel-text 取消按钮文案(空串 = 取内置多语言文案) String "" -
show-confirm 显示确认按钮(关闭后底部按钮区不渲染确认按钮) Boolean true -
show-cancel 显示取消按钮(关闭后底部按钮区不渲染取消按钮) Boolean true -
show-close 标题栏右侧关闭按钮(点击派发 cancel 并建议收起) Boolean false -
mask-closable 点击遮罩派发 close(遮罩来源信号)与 cancel 并回传 update:visible(false) 收起 Boolean true -
confirm-type 确认按钮类型:default = 中性灰底(与取消同形态,弱化主操作),其余为功能色填充 String "primary" primary / success / warning / error / info / default
cancel-type 取消按钮类型:default = 中性灰底(与确认形成主次对比),其余为功能色填充 String "default" primary / success / warning / error / info / default
buttons 自定义按钮组:非空时整组替代内置确认 / 取消两钮,点击派发 button-click 回传数组下标(不派发 confirm / cancel、不回传 update:visible,是否收起由使用者决定) Array [] -
button-direction 按钮排布方向:column = 竖排满宽(系统弹窗 / 长文案多钮常用) String "row" row / column
button-reverse 反转按钮顺序:默认两钮变「确认左、取消右」;buttons 模式反转视觉顺序(button-click 下标仍是 buttons 原下标) Boolean false -
button-model 按钮形态:button = 填充按钮(底色 + 圆角);text = 主次胶囊形态:功能色钮为实心胶囊(白字、胶囊圆角)、default 型为幽灵文字(灰字无底无框),横排并排 / 竖排堆叠,正文与操作区之间自动留呼吸间距 String "button" button / text
confirm-loading 确认按钮加载态:显示旋转加载圈并拦截点击(异步提交场景);仅对默认确认钮生效,buttons 模式无效 Boolean false -
top 面板垂直偏移(margin-top 值,负值上移:如 "-80px" 避开视线中心;空串 = 视口垂直居中) String "" -
z-index 弹层层级:0 = 跟随内置默认(1000);大于 0 时写入根节点行内 z-index(多弹层叠加时调高避让) Number 0 -
duration 出入场过渡时长(毫秒,透传 n-popup):0 = 即显模式(无过渡、瞬开瞬关) Number 300 -
width 面板宽度(如 "320px" / "84%"),透传 n-popup 的 size String "84%" -
content-align 正文水平对齐(仅对 content prop 文案生效;默认插槽内容由使用者自管对齐) String "center" left / center
custom-class 挂到根节点(n-popup 全屏透明层)的额外 class(调 z-index 等场景使用) String "" -
custom-style 根节点行内样式 String "" 与 css 相同

事件 ​

事件名 说明 回调参数
confirm 点确认按钮时触发;同帧回传 update:visible(false) 建议收起(组件不自行收起,收起由使用者把 visible 改回 false) -
cancel 点取消按钮 / 关闭按钮 / 遮罩(mask-closable 开启时)时触发;同帧回传 update:visible(false) -
close 点遮罩关闭时触发(仅 mask-closable 开启时的遮罩路径),与 cancel 同帧同发;单指遮罩来源,用于与按钮关闭区分 -
button-click buttons 按钮组模式点按钮时触发,参数为该按钮在 buttons 数组中的下标;不回传 update:visible,是否收起由使用者按业务决定 Number(下标)
update:visible 关闭建议(false):配合 :visible 手动双向控制显隐 Boolean

插槽 ​

插槽名 说明
header 标题区:替代 title 文案。提供时标题栏整块由此插槽填充,关闭按钮(show-close)仍渲染在右侧
default 正文主体:替代 content 文案。提供时整块正文区由此插槽填充,对齐由使用者自管
footer 底部操作区:替代默认确认 / 取消按钮。提供时不渲染内置按钮,整块底部由此插槽填充

实现说明 ​

  • 弹层骨架复用 n-popup:遮罩、居中面板、缩放淡入出入场、遮罩点击关闭全部由 n-popup(direction="center")承担,本组件只装配标题 / 正文 / 按钮三段内容。面板宽度经 n-popup 的 size 下发(width prop),圆角经 panel-style 覆写为对话框更贴的 12px(n-popup center 默认 16px,对话框收一档圆角);top 偏移同样经 panel-style 以 margin-top 下发;z-index 合入根节点 custom-style 行内下发。foot 节点 :key 收拢按钮全部配置位(形态 / 方向 / 来源 / 加载),任一翻转整区销毁重建(App 端动态插拔不重绘的已知问题)
  • 事件模型:确认按钮 → confirm + update:visible(false);取消 / 关闭钮 / 遮罩点击 → cancel + update:visible(false),遮罩点击另先派发 close(遮罩来源信号);buttons 模式 → button-click(下标),不回传 update:visible。组件不自行收起(与库内受控契约一致),收起由使用者把 visible 改回 false。n-popup 只绑定 @close(不绑定 @update:visible,避免双重派发)
  • 按钮自绘:按钮是简单 text + bg + 按压 opacity,不内嵌 n-button(遵循库内「零相互嵌入」架构——n-tag / n-cell 等均自绘内部图形)。六种类型色 + default 中性灰底,文字色随类型(填充取白、default 取墨);文本形态为主次胶囊:功能色钮实心胶囊白字、default 型幽灵灰字。禁用 = 保色相降透明 + JS 点击拦截(不绑原生 disabled);横排等宽(flex:1)、竖排满宽(列容器 stretch)
  • footer 插槽撑满宽:底部操作区是纵向容器,插槽内容自然撑满操作区宽(与 header / default 插槽同构);默认按钮组装在 btnrow 行容器内(横竖排 / 间距都在 btnrow 层装配)
  • 标题对齐随语境:无关闭钮时标题居中(对话框语境,与 content-align 默认居中同构,header 插槽同随容器居中);有关闭钮时左对齐(工具栏语境,标题贴左、关闭钮贴右)
  • 确认钮加载圈:confirm-loading 时确认钮内渲染旋转圈(JS 定时器驱动 transform,App 端无 CSS 动画,同 n-button),圈色与确认钮文字同源;加载 / 禁用期间点击被拦截、按压不反馈
  • 关闭按钮自绘:标题栏 × 是两条 view 杆 ±45° 交叠(纯 CSS,无字体依赖),同 n-cell 箭头 / n-color 对勾做法。杆位绝对定位(px,与 close-size 默认值 28px 联动)
  • 按钮间距:两形态统一 margin 留空(foot-gap,横排右距 / 竖排下距,仅非末钮挂,单按钮无多余边距);文本形态为加高按钮(btn-text-height,44px),正文与操作区之间的呼吸间距由正文段 body-text-pb 承担
  • 交互防抖:按钮 / 关闭钮点击派发即置位(同 n-popup 关闭请求守卫)——父组件回写 visible=false 后的退场过渡期间面板仍在屏上,再点不重复派发(双击回调只跑一次);父组件保持打开(异步提交不回写)时下一帧复位恢复交互,重开总是复位

机制对照 ​

与同类对话框组件(参考实现)的逐机制对照:

机制 参考做法 本库做法
调用范式 命令式 open(options) + callback(action) + 实例 close() / showLoading() 方法;或声明式 show prop 声明式受控 visible + 语义事件(confirm / cancel / close / button-click),组件不自行收起——显式优于隐式,与库内受控契约(n-popup / n-action-sheet)一致
异步关闭 asyncClose prop:点确认按钮不自动关闭,等业务回写 不设 prop:组件本就只回传「建议收起」(update:visible),不绑回写即不收起——同一能力由受控模型天然承担
异步加载 实例方法 showLoading() / hideLoading()(命令式范式配套) confirm-loading prop:确认钮内旋转加载圈 + 点击拦截;圈色随按钮类型(default 取墨、其余取白)
关闭前拦截 beforeClose(action, { close }) 钩子 confirm 回调里自行决定是否回写 visible(不满足条件就不改)——无需钩子,受控模型直写
自动关闭 duration 定时自动关(提示场景) 不收录:定时收起属 toast 语义(自动消失),模态对话框要求用户表态;需要时业务侧 setTimeout 改 visible
双击防抖 无(连点重复派发回调) 点击派发即置位:退场过渡期间再点不重复派发;保持打开时下一帧复位(见「实现说明 · 交互防抖」)
按钮颜色定制 逐钮 color / background / confirmColor / cancelColor / confirmBgColor / cancelBgColor 等十余色 prop 收敛为 confirm-type / cancel-type 六值类型枚举 + 主题令牌(--n-modal-*)——库内定制三通道哲学:日常走类型、深定制走令牌
按钮圆角 / 形状 buttonRadius / confirmButtonShape 等逐项 prop 令牌承担(btn-radius / btn-pill-radius)
面板圆角 / 内距 / 字号 round / boxRadius / padding / size / color / descrSize / descrColor 等几何样式 prop 令牌承担(radius / pad-x / title-size / content-size / content-line 等),见「定制」
遮罩色 maskBackground prop 弹层族统一遮罩令牌 --n-popup-mask-color(弹层骨架归 n-popup,遮罩视觉全族一致,可运行时覆盖)
缩放动画开关 zoom prop(true 缩放淡入 / false 仅淡入) 不收录:缩放淡入为 center 弹层固定语汇;无动画场景用 duration=0 即显
多按钮 buttons 数组(字符串或对象),点击 click 回传 {index, ...button} buttons 数组({text, type?, disabled?}),点击 button-click 回传下标(number)——类型化收窄,逐钮色走类型枚举
按钮竖排 / 反转 direction row/column;buttonReverse 同名收编:button-direction / button-reverse(反转后 button-click 下标仍为原数组下标)
关闭按钮 内置图标按钮(closeable) show-close:标题栏右侧纯 CSS 双杆 ×(无字体依赖,同 n-cell 箭头自绘先例);杆位与 close-size 令牌联动
标题对齐 恒居中 随语境:无关闭钮居中(对话框语境,与正文默认居中同构)、有关闭钮左对齐(工具栏语境,标题贴左 × 贴右)
正文对齐 无(恒居中) content-align left / center(仅对 content 文案生效,插槽内容自管)
生命周期事件 closed(命令式重置时机) 不透传:n-modal 场景收起即卸载、无档位/拖拽状态需要感知;弹层生命周期(open/opened/closed)由 n-popup 自身提供

定制 ​

主题令牌(--n-modal-* 运行时 CSS 变量,或 uni.scss 覆盖 $n-modal-*):面板圆角(radius)、内容区左右内距(pad-x)、标题字号(title-size)、正文字号 / 行高(content-size / content-line)、各段纵向间距(head-pt / head-pb / body-py / foot-pt / foot-pb)、按钮间距(foot-gap)、按钮高 / 圆角 / 字号 / 按压透明度 / 禁用透明度(btn-height / btn-radius / btn-size / btn-active / btn-disabled-opacity)、文本形态正文呼吸与按钮高(body-text-pb / btn-text-height)、胶囊圆角(btn-pill-radius)、关闭钮尺寸(close-size)。过渡时长走 duration prop(毫秒,0 = 即显)。根节点(全屏透明层)走 custom-class / custom-style(层级也可直接用 z-index prop)。

记录 · 思考 · 创作