uni-app 没有系统级顶部通知栏,需自定义组件+Pinia全局状态实现跨页面、可点击、自动销毁的顶部横幅;小程序仅支持模板消息,App/H5 可用 uni.showLocalNotification(需权限与版本适配)。

uni-app 没有“系统级顶部通知栏”这个东西——你在微信小程序里点开的所谓“通知”,其实是模板消息授权弹窗;真正在 App 前台显示的顶部横幅,得自己写组件+状态管理,不是调个 API 就完事。
uni-notice-bar 只能做静态通告,不能当通知栏用
它本质是滚动文字 banner,不带交互逻辑、不支持点击跳转参数、不维护生命周期、也不感知页面切换。你用它展示“系统升级中”,没问题;但想让它承载“订单 20261030001 已发货,点击查看”,就会卡在三处:
- 无法绑定动态
onClick回调传参(比如订单 ID) - 路由跳转时自动销毁,新页面进不来旧通知
- 没有优先级队列,多条消息会互相覆盖或堆叠错乱
真正要实现“顶部消息通知栏”,必须绕过 uni-notice-bar,改用自定义组件 + Pinia/Vuex 全局状态驱动。
App 和 H5 能用 uni.showLocalNotification,但小程序不行
uni.showLocalNotification 是 App/H5 专属 API,iOS ≥ 10、Android targetSdkVersion ≥ 26 才生效,且只在进程存活时触发。它根本不会在小程序环境执行——连报错都没有,静默跳过。
微信/支付宝/百度小程序平台禁止任何系统通知栏弹窗,只允许走官方订阅通道:uni.requestSubscribeMessage 请求授权 → 服务端调用模板消息接口下发 → 用户在微信聊天列表或服务通知页看到卡片。这不是“顶部通知栏”,而是平台级消息入口,前端无法控制样式、位置或入场动画。
真正在 App/H5 实现可交互顶部横幅,关键在三点
核心不是“怎么显示”,而是“怎么调度”。一个可用的顶部通知栏需满足:跨页面存在、支持点击跳转、自动销毁、不被导航栏遮挡。
- 状态层:Pinia store 中定义
notifications数组,每条含id、content、page(跳转路径)、query(参数对象)、onClose(关闭回调) - 组件层:固定挂载在
App.vue根节点下,用v-for渲染,配合<transition-group></transition-group>控制入场/离场;z-index: 999999确保压过 tabbar 和广告位 - 适配层:微信小程序启用自定义导航栏时,必须用
uni.getMenuButtonBoundingClientRect()动态算出顶部安全距离,不能写死top: 44px——否则 iPhone 15 Pro Max 上会被胶囊按钮切掉一半
最容易忽略的坑:消息点击后跳转失败
你以为传了 page: '/pages/order/detail' 就能跳?错。小程序要求该路径必须提前注册在 pages.json 的 pages 数组里,且 query 参数只能是字符串键值对,不能传对象或数组。App 端更麻烦:H5 跳转用 uni.navigateTo,App 端要用 uni.$emit 配合全局事件监听,否则子页面收不到 payload。
还有个隐形雷:安卓上如果没在 manifest 里声明 android.permission.POST_NOTIFICATIONS(targetSdkVersion ≥ 33 强制要求),通知横幅能渲染出来,但用户点击毫无反应——日志里连错误都不抛。


















