uni.navigateTo是最稳妥的页面跳转传参方式,支持URL参数(需encodeURIComponent编码中文)、extraData传对象(在onShow/onReady中获取),但参数仅单次单向传递;跨页状态同步应优先用uni.$emit/uni.$on或uni.setStorageSync。

uni-app 页面跳转传参用 uni.navigateTo 最稳妥
绝大多数场景下,uni.navigateTo 是唯一推荐的跳转方式,它支持 URL 参数、对象参数(通过 extraData)、以及路由守卫配合。别图省事直接改 url 字符串拼接,容易漏转义或被拦截。
常见错误现象:onLoad 拿不到参数、参数里中文变乱码、对象传过去变成 [object Object]。
- URL 参数必须是字符串,中文要用
encodeURIComponent包一层,比如:uni.navigateTo({ url: '/pages/detail/detail?id=1&title=' + encodeURIComponent('你好') }) - 想传对象?用
extraData,它不走 URL,不会被截断或编码污染,目标页onLoad里收不到,得在onShow或onReady里从getCurrentPages()取上一页实例再读options.extraData - H5 端对 URL 长度敏感,超过 ~2048 字符可能被截断;App 和小程序端对
extraData更友好,但注意它只在当前栈有效,页面关闭后就丢了
uni-app 页面间通信不能只靠跳转参数
跳转传参本质是「单次、单向、弱可靠性」的,一旦目标页被缓存、重定向、或用户手动刷新(H5),参数就丢了。真要跨页同步状态,得换思路。
使用场景:购物车数量 badge 实时更新、登录态变更后多个页面自动刷新、表单草稿临时共享。
- 优先用
uni.$emit/uni.$on:轻量、无侵入,适合事件驱动型通信,但要注意销毁监听(比如在onUnload里调uni.$off),否则内存泄漏 - 需要持久+全局?用
uni.setStorageSync存本地,比 Vuex 轻,也比globalData更可靠(globalData在 App 热更新或分包加载时可能重置) - 别用
getCurrentPages()直接改其他页面 data —— 小程序平台会报错,App/H5 虽然能跑,但破坏响应式,下次 setData 就覆盖掉
onLoad 拿不到参数?先查 options 来源和生命周期
很多人以为 onLoad 的 options 是“万能入口”,其实它只接收 URL query,且仅在页面首次加载时触发。很多问题出在这儿。
常见错误现象:onLoad 打印 options 是空对象、参数存在但没解构出来、H5 刷新后参数消失。
-
onLoad的options不包含extraData,那是onShow阶段才可访问的上下文信息 - App 和小程序中,如果页面被
keep-alive缓存,onLoad根本不执行,后续跳转只会触发onShow,此时要从getCurrentPages()找上一页的options或extraData - H5 端刷新页面会丢失所有 URL 参数(除非你手动把参数写进 history.state 或 localStorage),所以别依赖刷新后还能取到
onLoad.options
分包页面传参要注意路径和预加载限制
分包不是“完全隔离”,但传参链路上多了一层校验。路径写错、分包未声明、或提前预加载都可能让参数静默丢失。
使用场景:从主包跳转到 vendor 分包的订单页、从插件市场下载的分包模块回传数据。
- URL 必须写完整分包路径,比如
/subPackages/order/detail,不能只写/detail,否则 H5 会 404,小程序直接白屏 - 分包内页面无法用
extraData接收主包传来的对象——部分版本的 uni-app 在跨分包时会丢弃extraData,稳妥做法是全走 URL 参数(记得encodeURIComponent) - 如果用了
uni.preloadPage,预加载时不会执行onLoad,参数也不会提前注入,得等真正navigateTo后才生效
最麻烦的其实是「页面栈不可见状态」下的通信:比如 A → B → C,C 把数据塞给 A,但 A 已经 onHide 甚至被回收。这时候不能只盯着跳转 API,得结合存储 + 事件 + 页面实例生命周期来兜底。细节一多,很容易漏掉某端的兼容逻辑。

















