uni.navigateTo传参有三种主流方式:1.URL参数(需encodeURIComponent编码、手动类型转换);2.JSON字符串序列化传递对象;3.eventChannel实现双向通信(App/小程序支持,H5不支持)。

uni.navigateTo 是 uni-app 页面跳转传参最常用、最可靠的入口 API,但直接拼 URL 并不总能解决问题——尤其遇到中文、对象、长参数或跨端兼容时,容易踩坑。下面按真实开发中高频问题组织说明。
url 参数传参:简单值用这个,但必须处理编码和类型
适用于 id、name、status 这类字符串或数字型参数,比如 id=123&type=detail。关键不是“能不能拼”,而是“拼完能不能安全收”:
- 中文或特殊字符(如
&、=、空格)必须用encodeURIComponent()包裹,否则 URL 解析会错位,options.title可能截断或报错 - 所有 URL 传参都是字符串,
options.age === "25",不是25,需手动parseInt()或Number() - H5 端 URL 长度限制约 2048 字符,App 和小程序略宽松,但超长参数仍可能被截断,别硬塞大对象
- 示例写法:
uni.navigateTo({<br> url: `/pages/detail/detail?id=${id}&title=${encodeURIComponent(title)}`<br>});
JSON 字符串传参:对象/数组必须序列化再解码
想传一个 { id: 1, name: '测试', tags: ['a','b'] }?不能直接写进 URL,得先转成字符串再编码:
- 发送页:
url: `/pages/detail/detail?data=${encodeURIComponent(JSON.stringify(obj))}` - 接收页:
onLoad(options) { const obj = JSON.parse(decodeURIComponent(options.data)); } - 注意:如果
obj含 undefined、function、Date 实例等,JSON.stringify会丢掉它们,建议只传纯数据结构 - 别漏
decodeURIComponent—— 有些开发者只做JSON.parse,结果拿到的是乱码字符串
eventChannel 通信:适合跳转后双向交互,2.8.9+ 才支持
当目标页面需要“反向通知”上一页(比如选完地址后回传,或提交后刷新列表),eventChannel 比全局事件更干净:
- 跳转时启用:
uni.navigateTo({<br> url: '/pages/select-address/select-address',<br> events: {<br> acceptAddress: (data) => { console.log('收到地址:', data); }<br> },<br> success: (res) => {<br> // 向目标页发初始化数据<br> res.eventChannel.emit('initData', { city: '北京' });<br> }<br>}); - 目标页接收:
onLoad((options, route) => { const eventChannel = this.getOpenerEventChannel(); eventChannel.on('initData', handler); }) - 不支持 H5(文档明确标注),App 和小程序可用;若需全端兼容,得 fallback 到 storage 或
uni.$emit
别碰 extraData 和页面实例赋值
网上有方案让跳转后通过 getCurrentPages() 拿上一页实例、再挂 $vm.extradata,这方法看似灵活,实际隐患大:
- 时机难控:跳转是异步的,
success回调里取pages[pages.length - 2]在某些场景(如快速连点、分包加载延迟)会取到错误页面或undefined - 内存泄漏风险:把数据挂在页面实例上,页面销毁后若引用未清理,可能长期驻留
- 调试困难:这种隐式传递无法在 Vue Devtools 或路由日志里追踪,出问题只能靠 console 挨个打点
- 官方文档未将其列为正式传参方式,属于 hack 行为,后续版本可能失效
真正需要复杂状态共享时,优先用 uni.setStorageSync + 显式清理,或封装一个轻量 store,而不是依赖页面栈操作。


















