Uni-app 小程序页面跳转带参实战笔记(含对象传参与防坑)

这篇记录我在项目里踩过的坑:从列表页跳详情页时,参数传过去了但展示错乱(看起来像"写死")。

整理一份可复用的跳转带参方案,后续开发直接套。


一、跳转带参的底层逻辑

小程序页面跳转(uni.navigateTo)本质是:

  1. 在 A 页拼 URL query 参数
  2. 在 B 页 onLoad(options) 接收参数

options 里的值默认都是字符串。


二、最基础:传简单参数(id、name)

A 页面:发起跳转

复制代码
function goDetail() {

const id = 1001

const name = encodeURIComponent('内蒙古能源服务有限公司')

uni.navigateTo({

url: `/pages/detail/detail?id=${id}&name=${name}`

})

}

B 页面:接收参数

复制代码
import { onLoad } from '@dcloudio/uni-app'

onLoad((options) => {

const id = Number(options?.id || 0) // 字符串转数字

const name = options?.name ? decodeURIComponent(options.name) : ''

console.log('id:', id)

console.log('name:', name)

})

三、进阶:传对象参数(常用)

query 不能直接塞对象,需要先 JSON.stringify,再 URL 编码。

A 页面

复制代码
function goDetailWithObject(item: any) {

const data = encodeURIComponent(JSON.stringify(item))

uni.navigateTo({

url: `/pages/detail/detail?data=${data}`

})

}

B 页面

复制代码
onLoad((options) => {

let detailData: any = null

if (options?.data) {

try {

detailData = JSON.parse(decodeURIComponent(options.data))

} catch (error) {

console.warn('data parse failed:', error)

}

}

console.log('detailData:', detailData)

})

四、项目实战推荐:对象 + 关键字段兜底

这是我现在最推荐的模式,抗异常能力强。

为什么要"兜底"

  • 有些端上场景对象参数解析可能失败
  • 或者 URL 过长导致 data 不完整
  • 关键展示字段(如分数、等级、公司名)不能丢

A 页面(推荐写法)

复制代码
const encoded = encodeURIComponent(JSON.stringify(item))

const score = encodeURIComponent(String(item?.creditScore ?? ''))

const level = encodeURIComponent(String(item?.creditLevel ?? ''))

const companyName = encodeURIComponent(String(item?.companyName ?? ''))

uni.navigateTo({

url: `/pages_public/CustomerManagement/detail?id=${item.id}&data=${encoded}&creditScore=${score}&creditLevel=${level}&companyName=${companyName}&userStatus=${userStatus.value}`

})

B 页面(接收 + 合并)

复制代码
onLoad((options: any) => {

// 可选:统一解码工具

const decodeText = (value: unknown) => {

if (value === null || value === undefined) return ''

const text = String(value)

if (!text) return ''

try {

return decodeURIComponent(text)

} catch {

return text

}

}

let data: Record<string, any> | null = null

if (options?.data) {

try {

data = JSON.parse(decodeURIComponent(options.data))

} catch (error) {

console.warn('options.data parse failed:', error)

}

}

// 关键字段兜底

const scoreText = decodeText(options?.creditScore)

const levelText = decodeText(options?.creditLevel)

const nameText = decodeText(options?.companyName)

const fallbackFromQuery = {

companyName: nameText,

creditLevel: levelText,

creditScore: scoreText !== '' && Number.isFinite(Number(scoreText)) ? Number(scoreText) : undefined

}

// 合并优先级:默认值 < query兜底 < data对象

const finalDetail = {

companyName: '-',

creditLevel: '-',

creditScore: undefined,

...fallbackFromQuery,

...(data || {})

}

console.log(finalDetail)

})

五、常见坑清单(高频)

  1. 参数名不一致

    URL 写 companyName,接收写成 options.companyname,直接拿不到。

  2. 忘记 encode/decode

    中文、空格、&? 容易把 URL 搞坏。

  3. 把 options 当 number 用
    options.id 是字符串,记得 Number(...)

  4. 对象太大导致 URL 过长

    不要传超大对象,建议只传关键字段或只传 id

  5. 默认值写死引发误判

    fallback 默认值别写业务值(如"优秀/87"),应写中性值(-undefined)。


六、工程实践建议(最稳)

方案 A(最推荐)

  • 只传 id
  • 详情页根据 id 请求接口拿最新数据

**优点:**数据真实、长度安全、可控性强

**缺点:**首次展示依赖接口返回速度

方案 B(体验更好)

  • id + 关键展示字段
  • 先展示传参,再异步请求刷新

**优点:**秒开、又有最终一致性

**缺点:**代码稍复杂


七、我自己的结论

  • Demo 阶段:对象传参效率高
  • 线上阶段:id 拉取最稳
  • 折中最佳:id + 关键字段兜底 + try/catch 解析 + 中性默认值

八、可直接复用的"跳转模板"

复制代码
// A 页面

const payload = encodeURIComponent(JSON.stringify(item))

const companyName = encodeURIComponent(String(item.companyName ?? ''))

const score = encodeURIComponent(String(item.creditScore ?? ''))

const level = encodeURIComponent(String(item.creditLevel ?? ''))

uni.navigateTo({

url: `/pages/detail/detail?id=${item.id}&data=${payload}&companyName=${companyName}&creditScore=${score}&creditLevel=${level}`

})

// B 页面

onLoad((options) => {

let data = null

try {

data = options?.data ? JSON.parse(decodeURIComponent(options.data)) : null

} catch {}

const result = {

companyName: options?.companyName ? decodeURIComponent(options.companyName) : '',

creditScore: options?.creditScore ? Number(decodeURIComponent(options.creditScore)) : undefined,

creditLevel: options?.creditLevel ? decodeURIComponent(options.creditLevel) : '',

...(data || {})

}

// 使用 result

})
相关推荐
2301_768350233 小时前
Vue指令修饰符
前端·javascript·vue.js
oi..3 小时前
Flag和JavaScript document有关
开发语言·前端·javascript·经验分享·笔记·安全·网络安全
Sgf2273 小时前
2026Web前端进阶学习路线
前端·学习
ZTLJQ3 小时前
数据的另一面:Python中NoSQL数据库完全解析
开发语言·python·nosql
烧饼Fighting3 小时前
java+vue推rtsp流实现视频播放(由javacv+ffmpg转为vlcj)
java·开发语言·音视频
每天吃饭的羊3 小时前
computed 同时写 get() 和 set()
前端·javascript·vue.js
Highcharts.js3 小时前
Highcharts + TypeScript 集成高级技巧|类型与框架集成实战
前端·javascript·vue.js·react.js·typescript·highcharts·图表生成
芒果8013 小时前
做文档配图太烦?一个小时写了个工具解决
前端
luanma1509803 小时前
Vue2 vs Vue3:核心区别全解析
前端·javascript·vue.js