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

})
相关推荐
魔都吴所谓6 分钟前
【Python】 多线程 & 多进程&协程 常见题 + 应用场景整理
开发语言·python
king135987455019 分钟前
LiteRT Tensor API:C++ 编写端侧模型图,XNNPACK、GPU 与 NPU 怎么选?
开发语言·c++·人工智能·chatgpt·架构·aigc
geovindu20 分钟前
rust: Template Method Pattern(续)
开发语言·后端·设计模式·rust·行为模式·板方法模式
外收内放22 分钟前
面向对象高级(封装)
开发语言·python
tryCbest26 分钟前
Vue3——第 6 篇:事件处理与表单绑定——v-on 与 v-model
前端·javascript·vue.js
恋猫de小郭30 分钟前
Flutter 的文字为什么比 SwiftUI 更细?问题主要在 Skia 的 256 项查找表里
android·前端·flutter
lexiangqicheng32 分钟前
前端高阶面试核心通关指南:深入解析Vue3与React18底层原理及性能优化
前端·面试·性能优化
怕浪猫33 分钟前
前端对接聊天 API:我用 React 做了一个比 ChatGPT 还好看的界面
前端·后端·面试
devilnumber36 分钟前
Java 内部迭代 vs 外部迭代:从原理到实战避坑
java·开发语言
程序员小孔.37 分钟前
基于 Spring Cloud + Vue 的 JEEWMS 开源仓储管理平台设计与实现
前端·javascript·vue.js·spring boot·spring cloud·开源