ArkUI router 参数:详情页别假设参数一定有
【摘要】 今天我们用 pushUrl 带一组参数,再在目标页用 getParams 读出来。 参数传递很常见。列表点进详情、卡片打开编辑页、搜索页带筛选条件,都绕不开它。但这里有个坑:目标页不要默认参数一定完整。 只传简单数据 Demo 里传了三个字段: 这些都是可序列化的数据。Router 参数不要塞方法、系统对象、上下文对象
ArkUI router 参数:详情页别假设参数一定有
今天我们用 pushUrl 带一组参数,再在目标页用 getParams 读出来。
参数传递很常见。列表点进详情、卡片打开编辑页、搜索页带筛选条件,都绕不开它。但这里有个坑:目标页不要默认参数一定完整。
只传简单数据
Demo 里传了三个字段:
params: new RouterParamsPayload('路由参数演示', 'ArkUI Router', 3)
这些都是可序列化的数据。Router 参数不要塞方法、系统对象、上下文对象,也不要把整块复杂业务对象直接扔过去。
目标页要做缺省展示
目标页通过:
this.getUIContext().getRouter().getParams()
拿到参数对象。然后给 title、source、count 都准备缺省值。这样页面从其它入口打开、参数缺失、字段没带齐时,也能正常展示。
约束也一起记住
Router 页面栈最多支持 32 个页面。参数页同样是压栈,不要把每次筛选、每次点击都做成新页面。
另外,参数是页面之间的轻量信息,不是数据库,也不是全局状态。要长期保存的数据,应该放到更合适的存储方案里。
你写详情页时,有没有遇到过参数没带齐导致页面空白?这类问题通常不是组件问题,而是路由边界没兜住。
入口页完整代码
class RouterParamsPayload {
title: string
source: string
count: number
constructor(title: string, source: string, count: number) {
this.title = title
this.source = source
this.count = count
}
}
@Entry
@Component
struct ArkUIRouterParamsDemo {
private targetUrl: string = 'pages/arkUI/route/ArkUIRouterParamsTargetDemo'
@Builder
sectionTitle(title: string, desc: string) {
Column({ space: 6 }) {
Text(title)
.fontSize(19)
.fontWeight(FontWeight.Bold)
.fontColor('#111827')
Text(desc)
.fontSize(13)
.fontColor('#6B7280')
.lineHeight(20)
}
.width('100%')
.alignItems(HorizontalAlign.Start)
}
build() {
Scroll() {
Column({ space: 22 }) {
Column({ space: 8 }) {
Text('ArkUI router 参数')
.fontSize(28)
.fontWeight(FontWeight.Bold)
.fontColor('#111827')
Text('详情页别假设参数一定有')
.fontSize(16)
.fontColor('#4B5563')
Text('pushUrl 可以携带 params。目标页用 getParams 读取,但读取前要准备缺省值。')
.fontSize(14)
.fontColor('#6B7280')
.lineHeight(22)
}
.width('100%')
.alignItems(HorizontalAlign.Start)
this.sectionTitle('只传简单数据', 'params 适合放字符串、数字、布尔值这类可序列化数据,不要塞方法或系统对象。')
Column({ space: 10 }) {
Text('准备传给详情页的数据')
.fontSize(14)
.fontColor('#6B7280')
.width('100%')
Text('title: 路由参数演示')
.fontSize(15)
.fontColor('#111827')
.width('100%')
Text('source: ArkUI Router')
.fontSize(15)
.fontColor('#111827')
.width('100%')
Text('count: 3')
.fontSize(15)
.fontColor('#111827')
.width('100%')
}
.width('100%')
.padding(16)
.borderRadius(14)
.backgroundColor('#FFFFFF')
.border({ width: 1, color: '#E5E7EB' })
.alignItems(HorizontalAlign.Start)
Button('带参数打开详情页')
.fontSize(15)
.fontColor('#FFFFFF')
.height(44)
.borderRadius(22)
.backgroundColor('#0F766E')
.padding({ left: 22, right: 22 })
.onClick(() => {
this.getUIContext().getRouter().pushUrl({
url: this.targetUrl,
params: new RouterParamsPayload('路由参数演示', 'ArkUI Router', 3)
})
})
this.sectionTitle('目标页要兜底', '用户可能从别的入口进来,也可能没有拿到完整参数。详情页不要默认什么都有。')
Text('Demo 的目标页会给 title、source、count 都准备缺省展示。这样参数缺失时,页面也不会空着。')
.fontSize(14)
.fontColor('#374151')
.lineHeight(22)
.width('100%')
.padding(16)
.borderRadius(14)
.backgroundColor('#F9FAFB')
.border({ width: 1, color: '#E5E7EB' })
}
.width('100%')
.padding(24)
.alignItems(HorizontalAlign.Start)
}
.width('100%')
.height('100%')
.backgroundColor('#F3F4F6')
}
}
目标页完整代码
class RouterReceivedParams {
title?: string
source?: string
count?: number
}
@Entry
@Component
struct ArkUIRouterParamsTargetDemo {
@State title: string = '未收到标题'
@State source: string = '未收到来源'
@State countText: string = '0'
@State rawText: string = '{}'
aboutToAppear(): void {
let params = this.getUIContext().getRouter().getParams() as RouterReceivedParams
this.title = params.title ? params.title : '未收到标题'
this.source = params.source ? params.source : '未收到来源'
this.countText = params.count === undefined ? '0' : `${params.count}`
this.rawText = JSON.stringify(params)
}
@Builder
infoRow(label: string, value: string) {
Row({ space: 10 }) {
Text(label)
.fontSize(14)
.fontColor('#6B7280')
.width(72)
Text(value)
.fontSize(14)
.fontColor('#111827')
.layoutWeight(1)
}
.width('100%')
}
build() {
Scroll() {
Column({ space: 22 }) {
Column({ space: 8 }) {
Text('参数承接页')
.fontSize(28)
.fontWeight(FontWeight.Bold)
.fontColor('#111827')
Text('getParams 读到的是上一个页面带来的对象')
.fontSize(16)
.fontColor('#4B5563')
Text('这里故意给每个字段都准备了缺省值。详情页不要假设参数一定完整。')
.fontSize(14)
.fontColor('#6B7280')
.lineHeight(22)
}
.width('100%')
.alignItems(HorizontalAlign.Start)
Column({ space: 12 }) {
this.infoRow('标题', this.title)
this.infoRow('来源', this.source)
this.infoRow('数量', this.countText)
}
.width('100%')
.padding(16)
.borderRadius(14)
.backgroundColor('#FFFFFF')
.border({ width: 1, color: '#E5E7EB' })
Column({ space: 8 }) {
Text('原始参数')
.fontSize(16)
.fontWeight(FontWeight.Bold)
.fontColor('#111827')
.width('100%')
Text(this.rawText)
.fontSize(13)
.fontColor('#374151')
.lineHeight(20)
.width('100%')
}
.width('100%')
.padding(16)
.borderRadius(14)
.backgroundColor('#F9FAFB')
.border({ width: 1, color: '#E5E7EB' })
.alignItems(HorizontalAlign.Start)
Button('回到参数页')
.fontSize(15)
.fontColor('#FFFFFF')
.height(44)
.borderRadius(22)
.backgroundColor('#0F766E')
.padding({ left: 22, right: 22 })
.onClick(() => {
this.getUIContext().getRouter().back()
})
}
.width('100%')
.padding(24)
.alignItems(HorizontalAlign.Start)
}
.width('100%')
.height('100%')
.backgroundColor('#F3F4F6')
}
}
【版权声明】本文为华为云社区用户原创内容,未经允许不得转载,如需转载请自行联系原作者进行授权。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)