HarmonyOS鸿蒙Next中Router页面复杂对象如何传参
HarmonyOS鸿蒙Next中Router页面复杂对象如何传参 使用Router进行页面跳转传参时,数组、自定义实体类等对象如何传参给二级页面?
尊敬的开发者,您好,
使用 Router 进行页面跳转传参时,对于数组、自定义实体类等复杂对象,推荐通过JSON 序列化的方式传递
可以参考:基于router实现页面跳转功能
示例代码:
//一级页面pages/IndexPage.ets
import { router } from '@kit.ArkUI';
// 自定义实体类
class UserInfo {
name: string = '';
age: number = 0;
tags: string[] = [];
}
@Entry
@Component
struct IndexPage {
build() {
Button('跳转并传参')
.onClick(() => {
// 构造复杂对象
let user: UserInfo = {
name: '张三',
age: 25,
tags: ['开发者', '鸿蒙']
};
// 序列化后传递
router.pushUrl({
url: 'pages/SecondPage',
params: {
userData: JSON.stringify(user),
source: 'IndexPage'
}
});
});
}
}
//二级页面pages/SecondPage.ets
import { router } from '@kit.ArkUI';
class UserInfo {
name: string = '';
age: number = 0;
tags: string[] = [];
}
@Entry
@Component
struct SecondPage {
@State userName: string = '';
@State userAge: number = 0;
@State userTags: string[] = [];
aboutToAppear() {
// 获取参数并反序列化
const params = router.getParams() as Record<string, Object>;
if (params) {
try {
const userDataStr = params['userData'] as string;
const userData:UserInfo = JSON.parse(userDataStr);
this.userName = userData.name;
this.userAge = userData.age;
this.userTags = userData.tags;
} catch (error) {
console.error('参数解析失败', error);
}
}
}
build() {
Column() {
Text(`姓名:${this.userName}`)
Text(`年龄:${this.userAge}`)
ForEach(this.userTags, (tag: string) => {
Text(`标签:${tag}`)
})
}
}
}
问题解决方案:
请按照如下流程进行操作:
该问题可以参考的文档如下:
合作愉快。
华为开发者联盟
更多关于HarmonyOS鸿蒙Next中Router页面复杂对象如何传参的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
可以传,但建议传 纯数据对象 DTO,不要直接依赖实体类里的方法。Router 参数本质适合传可序列化数据:string、number、boolean、数组、普通对象。自定义类可以传字段,但对象里的方法不要传,二级页面需要方法时重新组装实体类。
示例代码:
一级页面:pages/Index.ets
import router from '@ohos.router';
class GoodsDto {
id: string = '';
name: string = '';
price: number = 0;
constructor(id: string, name: string, price: number) {
this.id = id;
this.name = name;
this.price = price;
}
}
class DetailParams {
title: string = '';
goodsList: GoodsDto[] = [];
selectedGoods: GoodsDto = new GoodsDto('', '', 0);
}
@Entry
@Component
struct Index {
private goodsList: GoodsDto[] = [
new GoodsDto('1001', '手机', 3999),
new GoodsDto('1002', '耳机', 699)
];
private jumpToDetail(): void {
let params = new DetailParams();
params.title = '商品详情';
params.goodsList = this.goodsList;
params.selectedGoods = this.goodsList[0];
router.pushUrl({
url: 'pages/Detail',
params: params
});
}
build() {
Column() {
Button('跳转详情页')
.onClick(() => {
this.jumpToDetail();
})
}
.width('100%')
.height('100%')
.justifyContent(FlexAlign.Center)
}
}
二级页面:pages/Detail.ets
import router from '@ohos.router';
class GoodsDto {
id: string = '';
name: string = '';
price: number = 0;
}
class DetailParams {
title: string = '';
goodsList: GoodsDto[] = [];
selectedGoods: GoodsDto = new GoodsDto();
}
@Entry
@Component
struct Detail {
@State title: string = '';
@State goodsName: string = '';
@State count: number = 0;
aboutToAppear(): void {
let params = router.getParams() as DetailParams;
this.title = params.title;
this.goodsName = params.selectedGoods.name;
this.count = params.goodsList.length;
}
build() {
Column({ space: 12 }) {
Text(this.title)
.fontSize(20)
Text(`选中商品:${this.goodsName}`)
.fontSize(16)
Text(`商品数量:${this.count}`)
.fontSize(16)
Button('返回')
.onClick(() => {
router.back();
})
}
.width('100%')
.height('100%')
.justifyContent(FlexAlign.Center)
}
}
注意点:
// 不建议传带方法的实体类
class Goods {
id: string = '';
name: string = '';
getDisplayName(): string {
return this.name;
}
}
如果二级页面需要 getDisplayName() 这类方法,建议只传 DTO 数据,到二级页面后重新构造业务实体。
大对象、图片二进制、超大数组不要直接走 Router 参数。更稳的做法是传 id,详情页再从缓存、数据库、AppStorage 或接口里取完整数据。
学习了
在 ArkUI 开发里 router 传参本身不适合直接传复杂对象。
Router 参数主要支持基础类型:
string
number
boolean
如果直接传:
router.pushUrl({
url: 'pages/detail',
params: {
list: myArray
}
})
数组、自定义对象可能会出现:
- 数据丢失
- 类型变成普通 Object
- 序列化异常
一般有几种处理方式:
方式1:JSON序列化(简单场景推荐)
跳转:
const data = {
id: 1,
name: 'test',
list: [1, 2, 3]
}
router.pushUrl({
url: 'pages/detail',
params: {
data: JSON.stringify(data)
}
})
目标页面:
const params = router.getParams()
const data = JSON.parse(params.data as string)
适合:
- 列表
- 详情数据
- 普通实体对象
方式2:只传id,二级页面重新查询(更推荐)
比如商品详情:
不要传整个商品:
{
id: 100,
name: 'xxx',
price: 99
}
直接:
router.pushUrl({
url: 'pages/detail',
params: {
id: 100
}
})
详情页:
根据 id:
- 数据库查询
- 或者请求接口
这个更符合实际项目。
方式3:使用 AppStorage / 状态管理共享
如果是页面间共享复杂数据:
比如:
- 用户信息
- 购物车
- 编辑状态
可以:
AppStorage.setOrCreate('userInfo', user)
目标页面:
const user = AppStorage.get('userInfo')
简单总结:
- 小数据:
JSON.stringify + JSON.parse - 大对象:传 id,目标页面重新获取
- 全局状态:AppStorage / 状态管理
不要直接通过 Router 传复杂对象,后面维护容易踩坑。
希望可以帮到你~~~
期待HarmonyOS能在未来推出更多针对企业用户的解决方案。
先说方案:序列化
其实大部分开发语言都是通用的,需要通过 Router 进行页面跳转传参时,对于数组、自定义实体类等复杂对象,肯定是不能直接传递,都必须要先进行序列化(通常使用 JSON.stringify),然后在目标页面接收时再反序列化(使用 JSON.parse)
router跳转的方式已过时,建议使用Navigation 方式跳转
可以直接通过 RouterOptions.params 传参。SDK 里 params 类型就是 Object,所以数组、普通对象都可以放进去;目标页再通过 getParams() 取出即可。建议尽量传“可序列化的普通数据”,自定义 class 实例不要依赖方法或原型在页面间保留,必要时在目标页按字段重新组装实例。
示例:
// 跳转页
interface UserInfo {
id: number
name: string
}
const users: UserInfo[] = [
{ id: 1, name: 'Tom' },
{ id: 2, name: 'Jerry' }
]
this.getUIContext().getRouter().pushUrl({
url: 'pages/SecondPage',
params: {
users,
extra: { from: 'home' }
}
})
// 目标页
aboutToAppear() {
const params = this.getUIContext().getRouter().getParams() as Record<string, Object>
const users = params['users'] as UserInfo[]
const extra = params['extra'] as Record<string, string>
}
如果你用的是老写法,也可以 import router from ‘@ohos.router’ 后使用 router.pushUrl({ url, params }) / router.getParams();不过较新的 API 中更推荐通过 UIContext 获取 Router。
注意两点:
- params 适合传页面初始化所需的小数据,不建议塞很大的列表、图片二进制、文件内容等。
- 如果对象很复杂或需要跨多个页面共享/修改,建议只传 id 或 key,真实数据放到 AppStorage、LocalStorage、全局状态管理或业务单例中,目标页按 key 再取。
HarmonyOS NEXT 使用 Navigation 路由,通过 NavPathStack.pushPath({ params: object }) 传递复杂对象。接收页在 aboutToAppear 中通过 this.params 获取。对象需为普通类或 @Observed 类,无需序列化。不建议使用已废弃的 Router 模块。,
在HarmonyOS Next中,router.pushUrl 的 params 字段支持基础类型(如string、number)以及JSON可序列化对象。对于数组或自定义实体类,需遵守以下规则:
- 自定义实体类必须实现
serialize和deserialize方法,或直接使用JSON.stringify序列化为字符串传递,接收方再解析。 - 数组可直接传递,但需保证内部元素为可序列化类型,或整体序列化为字符串。
示例代码:
// 发送页
import { router } from '@kit.ArkUI';
class User {
name: string;
age: number;
constructor(name: string, age: number) {
this.name = name;
this.age = age;
}
}
function send() {
let user = new User('Alice', 25);
let arr = [1, 2, 3];
router.pushUrl({
url: 'pages/Second',
params: {
user: JSON.stringify(user), // 序列化为字符串
arr: arr // 数组直接传
}
});
}
// 接收页
import { router } from '@kit.ArkUI';
import { JSON } from '@kit.ArkTS';
function receive() {
const params = router.getParams() as Record<string, Object>;
const userStr = params['user'] as string;
const user = JSON.parse(userStr) as User;
const arr = params['arr'] as number[];
}
注意:自定义实体类若直接作为 params 传递,需要实现 serialize/deserialize 方法,否则无法通过类型校验。推荐使用 JSON.stringify 处理自定义对象,简单可靠。数组若包含自定义对象,同样建议整体序列化。

