小程序通知栏提醒不能用uni.showToast,因其为模态轻提示、不支持跳转且无法持久显示;需通过自定义组件+Pinia/Vuex实现全局提醒队列,结合scope字段区分页面级与全局提醒,并注意微信小程序自定义导航栏兼容性及生命周期清理。

小程序端通知栏提醒为什么不能直接用 uni.showToast
因为 uni.showToast 是模态轻提示,不支持点击跳转、无法持久显示、也不能跨页面保持状态。真正在小程序里做“全局提醒管理”,本质是模拟一个常驻的顶部横幅(类似微信服务通知),靠自定义组件 + 全局状态驱动,而非调用原生 API。
如何用自定义组件 + vuex 或 pinia 实现全局提醒队列
核心思路是:把提醒消息存进全局 store,再由一个固定挂载在 App.vue 或主 layout 的组件监听并渲染。避免每个页面重复写逻辑,也防止路由切换后丢失状态。
- store 中定义
notifications数组,每条含id、content、type(info/warn/error)、duration、onClick回调 - 组件使用
v-for渲染,配合transition-group做入场/离场动画(uni-app 支持部分 Vue 过渡语法) - 每条消息自动倒计时关闭,但用户手动点击后应立即清除,并触发
onClick - 注意:小程序不支持
setTimeout在后台持续运行,所以倒计时必须在前台活跃时才生效;建议加个visible字段控制显隐,而不是直接从数组中splice
uni.getSystemInfoSync().platform === 'mp-weixin' 下的兼容细节
微信小程序对自定义顶部区域限制严格,尤其在启用了「自定义导航栏」(navigationStyle: custom)时,statusBar 高度和胶囊按钮位置必须手动计算,否则提醒栏会被遮挡或错位。
- 务必通过
uni.getMenuButtonBoundingClientRect()拿到胶囊按钮高度和 top,再结合statusBarHeight算出安全区域顶部偏移 - 不要写死
top: 0,否则 iPhone X+ 或安卓刘海屏会重叠状态栏 - 微信开发者工具里开启「启用自定义组件」选项,否则
slot和provide/inject行为异常 - 真机调试时发现提醒不显示?检查组件是否被
z-index更高的广告组件或 tabbar 盖住——小程序中z-index仅对同层节点有效,需确保提醒组件挂载在根节点下最外层
如何让通知支持“仅当前页面生效”和“全站强提醒”两种模式
实际业务中,有些提示(如表单校验失败)只该在当前页出现;有些(如系统维护公告)必须穿透路由强制展示。靠消息体里的 scope 字段区分即可,不需要额外封装两套组件。
-
scope: 'page':监听onPageScroll或onUnload自动销毁;也可结合getCurrentPages()判断当前页面路径匹配才显示 -
scope: 'global':无视路由变化,始终渲染;但需防重复添加——store 中用id去重,相同id再次 push 时更新内容或重置倒计时 - 避免在
onLaunch里直接 dispatch 提醒,此时页面尚未 ready,uni.$on订阅可能漏事件;稳妥做法是 store 初始化后延时 100ms 再触发首次渲染
真正难的不是显示,而是生命周期对齐:消息创建、页面卸载、小程序切入后台、用户手动清空……这些节点都要有明确的清理策略,否则残留定时器或闭包引用会导致内存泄漏。别省那几行 clearTimeout。


















