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

})
相关推荐
Imchendiana1 分钟前
《狂人日记NO.11》— 给 AI 装一本"项目说明书":我把"自己"蒸馏成了一个编码知识库Skill
前端·ai编程
l1258652 分钟前
# RAG多轮对话检索设计:Query重写如何让“那它呢“变成完整问题
前端·数据库·人工智能·python·算法·fastapi·milvus
এ慕ོ冬℘゜5 分钟前
前端实战:使用 jQuery 与 CSS3 打造动态数据表格与滑块交互
前端·css3·jquery
Csvn6 分钟前
✂️ AbortController:一个 API 统一取消 fetch、事件监听与 AI 流式请求
前端
invicinble9 分钟前
对于vue2转vue3相关技术整合
前端
MacroZheng18 分钟前
腾讯又开源了一个新项目,用起来真优雅!
前端·vue.js·人工智能
如此这般英俊32 分钟前
手搓Claude Code-第十三章 background_tasks
前端·人工智能·chrome·python·算法·语言模型·自然语言处理
人间凡尔赛35 分钟前
Angular 20 告别 Zone.js:Zoneless 无 Zone 时代正式开启,Signals 驱动的响应式新范式(附完整代码)
前端·angular
君顾135 分钟前
智慧场馆解决方案小程序系统开发实战指南
java·开发语言·智慧场馆