uni.showModal 是阻塞式模态对话框,用于删除确认、支付核对等需用户明确响应的场景;uni.showToast 是非阻塞轻提示,仅适用于“提交成功”等瞬时反馈,二者不可互换。

uni.showModal 和 uni.showToast 不是同类组件,不能互换使用——前者是阻塞式确认弹窗,后者是非阻塞式轻提示;强行用 uni.showToast 替代确认逻辑,用户点完就走,根本收不到反馈。
uni.showModal 是什么,什么时候必须用它
它是一个模态对话框,会暂停用户对页面其余部分的操作(底层加了透明蒙层),强制用户做选择。典型场景包括:删除前二次确认、支付前核对金额、退出页面时询问是否保存。
- 调用后立即阻塞交互,
mask: true默认生效,不可穿透 - 回调中必须检查
res.confirm或res.cancel,否则无法区分用户意图 - 不支持自定义 DOM 结构,样式完全由平台原生渲染(iOS/Android/H5 表现略有差异)
- 在 App 端,如果页面有
position: fixed元素(如底部导航栏),且 z-index 过高,uni.showModal可能被遮挡——这不是 bug,是层级管理失效
uni.showToast 适合干啥,哪些情况千万别用它
它只是个短暂浮层,3 秒自动消失,不打断用户操作流。适用于“已提交”“复制成功”“加载完成”这类无须响应的瞬时反馈。
- 默认不带蒙层(
mask: false),点击背景或其它按钮照常触发 -
icon参数控制图标:可选"success"、"loading"、"none";填错值(比如"check")会导致图标不显示 - 设置
duration: 10000并不能让它“一直挂着”,App 端上限约 10 秒,H5 端可能更短,超时仍会自动隐藏 - 不要用它替代表单校验失败提示——用户没时间看,也点不了重试
为什么局部写 z-index 对它们无效
因为 uni.showToast 和 uni.showModal 的 DOM 节点不是插在当前页面组件内,而是由 UniApp 框架统一挂载到 #app 根节点之外的独立容器里(例如 uni-toast、uni-modal)。你在 pages/index.vue 的 <style> 里写的 .uni-toast { z-index: 9999; },根本作用不到那个真实节点上。
- 正确做法是把样式写进
App.vue的全局<style>块里 - 必须用框架实际生成的类名:
.uni-toast、.uni-modal、.uni-loading - 推荐写法:
.uni-toast, .uni-modal, .uni-loading { z-index: 999999 !important; } - 加
!important是必要的,因为框架内联样式可能带权重,普通声明会被覆盖
遇到遮挡问题,先别改代码,检查这三处
很多开发者一上来就翻源码、写 hack,其实 80% 的遮挡问题出在基础配置上。
- 确认你没在页面根元素或导航栏上设过高的
z-index(比如9999),应控制在99以内 - 检查是否启用了
vue.config.js中的css.extract,开启后可能导致样式注入时机错乱 - H5 端若用到了第三方 UI 库(如 uView、uView2),它们的弹窗组件可能和
uni.系列冲突,建议禁用其内置 toast/modal,统一走uni.API
真正难处理的是多层 fixed 定位叠加 + 动态插入 DOM 的混合场景,比如一个自定义全屏遮罩 + 底部 tabbar + 页面内 fixed 搜索栏——这时候光调 z-index 不够,得配合 pointer-events: none 控制穿透性,但要注意别误伤可点击区域。


















