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

})
相关推荐
星星在线2 小时前
MusicFree:一个「All in One」的个人音乐服务器,让听歌回归简单
前端·后端
IT_陈寒3 小时前
Redis的SETNX并发问题让我加了三天班
前端·人工智能·后端
demo007x3 小时前
Docling 文档转换以及技术架构分析
前端·后端·程序员
京东云开发者4 小时前
京东市民服务又“上新”!这次是黑龙江“龙易办”
前端
袋鱼不重4 小时前
我的神奇同事,AI 用多了居然写了个 Open In Codex
前端·后端·ai编程
竹林8185 小时前
Web3表单签名验证:我用 wagmi 和 ethers 给 DApp 加了一个“免密登录”,踩坑记录全在这了
javascript
用户6990304848755 小时前
try catch使用场景 处理同步代码错误兼容用的
javascript·uni-app
LDR0065 小时前
Type-C 快充全面升级!LDR6601 赋能个人护理便携电机,重塑剃须刀 / 理发器新体验
c语言·开发语言
雪碧聊技术5 小时前
Tree.js是什么?一文讲透
开发语言·javascript·ecmascript
码云数智-园园5 小时前
C++20 Modules 模块详解
java·开发语言·spring