离线推送点击跳转必须用 plus.push.addEventListener('click', ...),因 onLaunch/onShow 在 iOS 热启动和 Android 全场景均无法获取 payload;iOS 的 msg.payload 是对象,Android 是字符串,需类型判断后解析;跳转前须 setTimeout 延迟并校验路由合法性。

离线推送点击跳转必须用 plus.push.addEventListener('click', ...),不能只靠 onLaunch 或 onShow 捕获参数 —— 真机上 iOS 热启动、Android 全场景都会丢 payload。
为什么 onLaunch/onShow 拿不到离线点击的跳转参数
uni-app 的 onLaunch 只在冷启动时触发,且 iOS 仅在冷启动时可能带 options.push 字段;Android 完全不透传。App 被杀死后用户点击通知栏消息,系统是通过原生 Intent(Android)或 application:didReceiveRemoteNotification:fetchCompletionHandler:(iOS)把 payload 传进来的,uni-app 默认生命周期钩子根本收不到原始数据。
-
onLaunch的options在 Android 上永远为空,在 iOS 热启动时也为空 -
onShow不接收任何推送字段,只反映前台切换状态 - 离线消息的 payload 必须由
plus.push.addEventListener('click', ...)捕获,这是唯一稳定入口
plus.push.addEventListener('click', ...) 的双端写法差异
iOS 和 Android 的 msg 结构不一致,直接 JSON.parse(msg.payload) 会崩:iOS 的 msg.payload 是对象,Android 是字符串;部分厂商通道(如华为)还额外塞了 msg.intent 或 msg.extra。
- iOS:
msg.payload是服务端下发的 JSON 对象(需服务端配置content-available=1) - Android:
msg.payload是字符串,必须先JSON.parse();华为/小米等通道可能需从msg.extra提取 - 统一处理建议:
const payload = msg.payload ? (typeof msg.payload === 'string' ? JSON.parse(msg.payload) : msg.payload) : {};
点击后跳转页面失败的常见原因
在 plus.push 回调里直接调用 uni.navigateTo 大概率白屏或无响应 —— 此时 Vue 实例可能未就绪,uni API 尚未挂载完成。
- 必须加防抖或延迟:用
setTimeout(() => { uni.navigateTo(...) }, 300)确保路由系统可用 - 避免重复跳转:离线点击可能触发多次(尤其厂商通道),建议用
uni.setStorageSync缓存一次 payload,进入首页后再清空 - 路由路径必须合法:不能带
.vue后缀,不能用绝对路径(如/pages/detail要写成pages/detail) - 若跳转目标是 tabBar 页面,要用
uni.switchTab,否则报错
App.vue 中监听注册的正确时机和位置
监听器必须在 App 启动最早期挂载,否则事件会丢失。不能放在 mounted 或页面级 onLoad,必须在 App.vue 的 onLaunch 里注册。
- 推荐写法:
onLaunch() { if (uni.getSystemInfoSync().platform === 'app') { plus.push.addEventListener('click', this.handlePushClick, false); } }, methods: { handlePushClick(msg) { const payload = msg.payload ? (typeof msg.payload === 'string' ? JSON.parse(msg.payload) : msg.payload) : {}; setTimeout(() => { uni.navigateTo({ url: `/pages/detail?id=${payload.id}` }); }, 300); } } - 注意:
plus.pushAPI 仅在APP-PLUS环境有效,H5 和小程序里要包裹#ifdef APP-PLUS - 云打包前务必确认 DCloud 后台已配置对应厂商(华为/小米等)的离线通道,否则
plus.push根本收不到 click 事件
离线跳转最易被忽略的点是:没做 payload 类型校验、没处理 Android 字符串解析、没加 setTimeout 延迟跳转 —— 这三处任一缺失,真机上都表现为“点了通知没反应”。


















