跨平台获取URL参数需分端处理:小程序/App端优先用onLoad(options)并decodeURIComponent;H5端优先this.$route.query(hash模式),否则解析window.location.hash;须手动判断平台并容错处理。

uni-app 解析 URL 参数不能只靠一种方式,得看参数在哪、跑在哪端、什么时候取——onLoad 拿不到的,this.$route.query 可能根本不存在;window.location.search 在 H5 hash 模式下是空的;小程序里 this.$route 就是 undefined。
onLoad(options) 是小程序和 App 端最稳的入口
页面加载时,框架会把 URL 中 ? 后的键值对自动解析为对象传给 onLoad,这是跨小程序(微信/支付宝)、App 端最可靠的方式。
-
options是纯对象,不带 URL 编码,但中文、空格、斜杠等仍为编码态,必须手动decodeURIComponent,比如options.name是%E4%BD%A0%E5%A5%BD,要写成decodeURIComponent(options.name || '') - 重复参数如
?id=1&id=2会被后一个覆盖,无法感知多值 - 路径部分(如
/pages/detail/detail)不在options里,需用getCurrentPages().pop().route拼接(注意:小程序某些平台该值可能为undefined) - 冷启动(从桌面图标或分享卡片进入)时,
onLoad一定触发;热启动(后台切回)可能只走onShow,所以关键逻辑别只写在onLoad里
this.$route.query 只在 H5/APP 的 hash 模式下有效
这个 API 本质是 Vue Router 的封装,仅当 manifest.json 中 h5.router.mode 设为 "hash" 且参数出现在 # 后路径中时才可用。
- URL 必须形如
https://example.com/#/pages/detail?id=123,而不是https://example.com/?id=123#/—— 后者window.location.search能取到,但this.$route.query为空 - 不能在
created或mounted钩子中直接读,H5 端路由初始化有延迟,优先放在onLoad或onShow里取 - 如果用了
uni.redirectTo或uni.reLaunch,原始 hash 参数大概率被清空,需在跳转前用uni.setStorageSync临时缓存 - 若误将
h5.router.mode设为"history",this.$route.query全失效,此时应改用window.location.search
window.location.hash 是 H5 端兜底解析的唯一可信源
当路由未初始化、this.$route 不可用,或需要绕过框架直接读原始字符串时,window.location.hash 返回完整 hash 值(如 "/pages/detail?id=123&token=abc"),它永远真实。
- 开头可能带
/或/?,建议先用正则提取 query 部分:const queryMatch = window.location.hash.match(/[?&](.*)$/),再用new URLSearchParams(queryMatch?.[1] || '') - 避免手撕字符串:不用
split('?').pop(),因为参数值里可能含?(虽然少见) - 该方式在小程序里无效(
window对象不可用),仅限 H5 - 注意:
window.location.hash在页面首次加载时即存在,但若路由重定向频繁,需防重复解析
跨平台统一取参必须自己封装分支逻辑
没有一行代码能通吃所有端。想在同一个方法里安全取参,必须显式判断平台并选不同路径:
- 先用
uni.getSystemInfoSync().platform区分"ios"/"android"/"mp-weixin"等 - 小程序端:只信
onLoad(options)和uni.getLaunchOptionsSync().query - H5 端:优先
this.$route.query(确认 mode 是 hash),fallback 到new URLSearchParams(window.location.hash.slice(1)) - APP 端:
onLoad(options)主力,uni.getLaunchOptionsSync()补充冷启参数 - 所有 decode 操作必须加
try/catch,旧版客户端可能传非法编码串
最易被忽略的是:参数来源不止一次,onLoad 和 onShow 可能先后触发,而 uni.getLaunchOptionsSync() 返回的是首次启动快照,后续页面切换不会更新——如果你在埋点或权限校验里混用这三者,结果很可能错位。











