必须用plus.push.addEventListener监听原生推送点击事件,因uni-app的onLaunch/onShow不透传iOS/Android系统级推送参数,仅冷启动时iOS的onLaunch可能含push字段,热启动及Android全平台均需依赖该原生API捕获payload。

不能只靠 onLaunch 或 onShow 捕获推送点击事件,真机上必须用 plus.push.addEventListener 监听原生推送到达和点击行为,且 iOS 和 Android 的触发时机、参数结构完全不同。
为什么 onLaunch/onShow 拿不到推送点击参数?
uni-app 的 onLaunch 只在 App 启动时触发,onShow 在前台显示时触发,但它们接收不到推送点击携带的 payload。当用户点击通知栏消息启动 App(或从后台唤醒),iOS 会通过 application:didReceiveRemoteNotification:fetchCompletionHandler: 传递数据,Android 则走 Intent 的 extras。uni-app 封装层默认不透传这些原始参数,必须绕过 JS 层生命周期,直接监听原生 push 事件。
- iOS:推送点击后首次进入 App,
onLaunch的options中可能有push字段,但仅限冷启动;热启动(App 在后台)时该字段为空,必须依赖plus.push.addEventListener('click', ...) - Android:无论冷/热启动,
onLaunch和onShow都不会自动注入推送内容;只有plus.push.addEventListener('click', ...)能稳定拿到payload和type - 注意:
plus.pushAPI 仅在 App 端(非 H5/小程序)可用,且需在App.vue的onLaunch中初始化并注册监听,否则监听器未挂载就错过事件
plus.push.addEventListener('click', ...) 的实际写法与参数差异
监听必须在 App 启动早期注册,推荐放在 App.vue 的 onLaunch 中。回调函数收到的 msg 对象在双端结构不一致:
- iOS:
msg.aps.alert是通知文案,msg.payload是你服务端下发的自定义 JSON(需确保服务端配置了content-available=1或启用静默推送) - Android:
msg.content是通知正文,msg.payload是字符串形式的 JSON(需JSON.parse(msg.payload)),部分厂商通道(如华为、小米)还会额外带msg.intent或msg.extra - 务必检查
msg.type === 'click',因为plus.push同时会触发receive(到达)和click(点击)两种事件,不要混淆 - 示例代码片段(放在
App.vue的onLaunch内):
plus.push.addEventListener('click', (msg) => {
if (msg.type !== 'click') return;
const payload = msg.payload ? (typeof msg.payload === 'string' ? JSON.parse(msg.payload) : msg.payload) : {};
// 跳转逻辑,例如:uni.navigateTo({ url: '/pages/detail?id=' + payload.id });
}, false);
点击通知跳转页面时的路由兼容性陷阱
直接在 plus.push 回调里调用 uni.navigateTo 会失败,因为此时 Vue 实例尚未就绪,uni API 可能不可用或页面栈未初始化。
- 正确做法:用
setTimeout延迟 100–300ms,等 App 主线程稳定后再跳转;更稳妥的是把 payload 存到uni.setStorageSync,然后在首页onShow中读取并跳转 - 避免跳转目标页不存在:服务端下发的
url字段必须是已注册的 pages 路径,且不能含 query 参数以外的非法字符;建议前端做白名单校验,比如只允许跳转/pages/order、/pages/news等固定路径 - Android 上部分厂商 ROM(如 OPPO、vivo)会拦截 Intent 启动,导致跳转失效;若发现跳转无响应,需检查是否被系统优化限制,引导用户手动开启「自启动」和「关联启动」权限
测试阶段最容易漏掉的三个真机验证点
模拟器无法测试推送点击,所有验证必须在真机上完成,且要分场景覆盖:
- App 杀死状态(冷启动)下点击通知:验证
onLaunch是否能拿到初始参数,plus.pushclick 监听是否触发 - App 后台运行(热启动)下点击通知:这是最常出问题的场景,
onShow不会带参数,全靠plus.push监听;iOS 还需确认是否启用了 Background Modes 中的 Remote notifications - 用户关闭通知权限后点击通知:此时系统根本不会展示通知,也就没有点击事件;必须前置检测权限(用
uni.getPushPermission或uni.authorize('scope.notification')),不能等到点击才处理
真正难的不是写监听代码,而是让 iOS 的静默唤醒、Android 的多厂商通道、以及用户手动关闭权限这三者同时在线且行为可预期——每个环节断掉,点击跳转就变成“点了没反应”。











