uni-app小程序端点击列表项跳转页面参数丢失怎么办?
在开发小程序列表页时遇到个奇怪的问题,用uni.navigateTo跳转时传递的参数到新页面就拿不到了。
我按照文档写了个列表循环,点击事件里这样写的:
点击跳转
export default {
methods: {
goDetail(id) {
uni.navigateTo({
url: `/pages/detail?id=${id}`
})
}
}
}
然后在detail页面onLoad里用console.log(e)看参数,发现对象里啥都没有。但如果是用按钮直接跳转固定参数就能拿到,为什么动态传参就不行呢?试过把id转字符串也不行,难道是路径写错了?
首先你要改的是goDetail方法里的传参方式。不能写成url:
/pages/detail?id=${id},而是要把参数单独提出来写成对象:export default {
methods: {
goDetail(id) {
uni.navigateTo({
url: '/pages/detail',
success: (res) => {
// 这里可以做一些页面跳转后的操作
},
fail: (err) => {
console.log('跳转失败', err)
}
})
// 这里才是传参的关键步骤
uni.$emit('detailParams', { id: id })
}
}
}
然后在你的detail页面里,需要用uni.$on来监听这个事件,获取到参数:
// pages/detail/detail.vue
export default {
onLoad() {
uni.$on('detailParams', (params) => {
console.log('接收到的参数', params)
// 这里就可以拿到params.id了
})
}
}
为什么这样改呢?因为小程序的页面跳转url传参有长度限制,而且只能传字符串类型的参数。通过uni.$emit这种方式传参,本质是利用了全局事件总线来传递数据,能够支持传对象、数组等复杂类型的数据,也避免了url拼接的问题。
另外,你原来的写法url:
/pages/detail?id=${id},在H5端可能是能正常工作的,因为H5端的页面跳转就是基于url的,但是在小程序端就不行了。这是因为小程序的页面传参机制和H5不同,它本质上是通过原生组件跳转的,url传参只是兼容H5的一种特殊处理方式。还有一个需要注意的点是,uni.$emit传参是全局的,如果你有多个页面都监听了同一个事件名,可能会出现数据被多个页面同时接收到的情况。所以建议在页面卸载的时候取消监听:
// pages/detail/detail.vue
export default {
onLoad() {
this.handleDetailParams = (params) => {
console.log('接收到的参数', params)
}
uni.$on('detailParams', this.handleDetailParams)
},
onUnload() {
uni.$off('detailParams', this.handleDetailParams)
}
}
这样就能避免页面卸载后还接收到事件的问题了。总结一下,遇到这种问题主要是因为url传参在小程序端不适用,需要用uni.$emit这种方式来传参。
1. 首先是跳转路径,确保
pages/detail这个页面已经在小程序的pages.json里注册了,不然肯定拿不到参数。2. 然后是在 detail 页面里获取参数的方式要对。你用的是
onLoad(e),这没问题,但要注意传过来的参数都在e对象里,比如这里的id。你可以试试下面这段代码,保证能跑通:
在列表页:
注意这里用了
encodeURIComponent,是为了防止特殊字符导致参数解析出错。然后在 detail 页面:
这样基本就没问题了。如果还是拿不到参数,那大概率是
pages.json里没配对页面路径,或者有其他地方覆盖了跳转逻辑。检查一下这些细节就好。开发这种事情嘛,很多时候就是掉进这种小坑里,我以前也老是被参数传递折腾得头疼,后来发现大多都是这种编码或者配置的小问题。