小程序端无法实现真正意义上的动态路由注册,pages.json必须提前声明所有路径,动态路由仅限参数驱动;uni.navigateto传参只能通过query字符串,需encodeuricomponent编码且url总长≤1024字节;接收参数唯一可靠方式是onload(option),不可依赖this.$route.query或mounted;复杂数据用eventchannel替代;分包路径须带前缀且静态声明;tabbar页面只能用uni.switchtab;权限控制需服务端+前端双重校验。

小程序端无法实现真正意义上的动态路由注册,pages.json 必须提前声明所有可跳转路径,所谓“动态路由”只能在已注册路径上做参数驱动的逻辑分发。
uni.navigateTo 传参必须走 query 字符串
小程序平台(微信/支付宝等)不支持 Vue Router 风格的命名路由或 params 模式,所有参数都得拼进 url 的 query 部分。直接写 url: '/pages/detail/detail?id=123&status=done' 是唯一可靠方式。
- 不能用对象传参:
uni.navigateTo({ url: '/pages/detail/detail', query: { id: 123 } })❌ 小程序端会忽略query字段 - 特殊字符必须编码:
encodeURIComponent包裹值,尤其是中文、空格、斜杠等,否则跳转失败或参数截断 - URL 总长度建议控制在 1024 字节内,超长可能被截断或触发白屏(尤其 iOS 微信)
接收参数只能靠 onLoad(option) + this.$route.query
目标页面生命周期钩子 onLoad 的参数 option 是唯一可信入口,this.$route.query 在某些平台(如 H5)可用,但在小程序里不稳定,部分版本甚至为 undefined。
- 务必在
onLoad中解构:onLoad(option) { const id = option.id; const name = option.name; } - 不要依赖
mounted或created:此时option已不可读,this.$route可能未就绪 - 如果传的是复杂对象,先
JSON.stringify再encodeURIComponent,接收端反向decodeURIComponent+JSON.parse
eventChannel 是跨页通信的替代方案,不是路由参数
当 query 无法承载大量数据(比如整个列表项对象),或需要双向通信(回传修改结果),eventChannel 才是正解。但它和“路由参数”本质不同——它不改变 URL,也不进入页面栈历史,只在两个页面实例间建立临时通道。
- 发起页需在
uni.navigateTo中显式声明events对象并传eventChannel.emit - 目标页通过
this.getOpenerEventChannel()获取通道,并用on监听或emit发送 - 注意生命周期:若目标页被销毁(如
redirectTo替换),通道自动关闭,监听器失效
pages.json 路径必须静态存在,别幻想运行时注册
哪怕你用变量拼出 /subpkg/order/detail,这个路径也必须提前写死在 pages.json 的 subPackages 或 pages 数组里。否则跳转直接报错 page not found,且无任何提示。
- 分包路径要带前缀:
/subpkg/order/detail,不能漏掉开头的/和subpkg/ - TabBar 页面只能用
uni.switchTab,且路径必须在tabBar.list中声明,query参数会被丢弃 - 权限控制不能靠隐藏路由,而应结合服务端下发菜单结构 + 前端校验跳转前权限,否则容易被 URL 手动篡改绕过
最易忽略的一点:小程序页面栈是独立 JS 上下文,this.$router 全局不可用,meta 字段无法注入,所有路由逻辑必须收口到跳转前的手动判断和页面内的 onLoad 处理中。










