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