HarmonyOS鸿蒙Next中在Router的传递数据的过程中,如何封装自定义的对象传递到另外一个页面?
HarmonyOS鸿蒙Next中在Router的传递数据的过程中,如何封装自定义的对象传递到另外一个页面?
使用ArkTS(一种为鸿蒙系统设计的TypeScript超集)进行页面间数据传递时,过程与在普通 TypeScript 环境或Android原生开发中类似。在鸿蒙系统中,页面之间的导航和数据传递通常通过Ability(能力)和Intent来实现。以下是在鸿蒙开发中,使用ArkTS封装自定义对象并传递到另一个页面的步骤:
- 定义自定义对象:
首先,你需要定义一个自定义的TypeScript类(在ArkTS环境中),这个类将包含你想要传递的数据。
export class User {
id: number;
name: string;
email: string;
constructor(id: number, name: string, email: string) {
this.id = id;
this.name = name;
this.email = email;
}
}
- 通过Router传递参数
更多关于HarmonyOS鸿蒙Next中在Router的传递数据的过程中,如何封装自定义的对象传递到另外一个页面?的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
【背景知识】
-
@ohos.router (页面路由)页面跳转并传递参数的四种方式:
- router.pushUrl,通过页面Url方式实现页面推送跳转,将指定页面页面推送至路由栈顶层渲染显示;
- router.replaceUrl,通过页面Url方式实现页面替换跳转,将当前顶层页面替换成指定页面渲染显示;
- router.pushNamedRoute,通过页面名字实现页面跳转,将指定页面页面推送至路由栈顶层渲染显示;
- router.replaceNamedRoute,通过页面名字实现页面跳转,将当前顶层页面替换成指定页面渲染显示。
-
参数形式:
-
其中router.pushUrl与router.replaceUrl描述页面信息的参数为RouterOptions,传递参数结构形式为:
{ url: 'XXX/XXX/XXX', // 传递的方式,必填参数 params: Object, // 传递的数据,必填参数,可以是基础类型或者自定义数据类型 recoverable: true // 页面是否可恢复,该参数为非必填参数,默认为true }
-
router.pushNamedRoute与router.replaceNamedRoute描述页面信息的参数为NamedRouterOptions,传递参数结构形式为:
{ name: 'XXX', // 传递的方式,必填参数 params: Object, // 传递的数据,必填参数,可以是基础类型或者自定义数据类型 recoverable: true // 页面是否可恢复,该参数为非必填参数,默认为true }
-
注意事项:params不支持传递方法和系统返回的对象。
【解决方案】
定义一个自定义的TypeScript类
// 示例:对象传参
// 封装自定义的对象
class Person {
name: string = '';
info: Info = {}
}
class Info {
age?: number = 0
}
router.pushUrl({
url: 'pages/Second',
params: {
name: "Welcome",
info: {
age: 20
}
}
})
除传参外,需要确认获取参数的方式:router.getParams。获取的参数数据结构和传递的参数一致。
接收router传递的参数方案:
// 建议使用this.getUIContext().getRouter().getParams()
@State params: ParamInfo = router.getParams() as ParamInfo
aboutToAppear(): void {
// 方案一
let params = (router.getParams() as Record<string, object>)
let name = params["name"]
let info = params["info"]
console.log("方案一:" + JSON.stringify(params) + " name:" + name + " info:" + info)
// 方案二
let params2: object = Object(router.getParams())
console.log("方案二:" + JSON.stringify(params2) + " name:" + params2["name"] + " info:" + params2["info"])
// 方案三
let paramInfo: ParamInfo = router.getParams() as ParamInfo
console.log("方案三:" + JSON.stringify(paramInfo) + " name:" + paramInfo.name + " info:" + paramInfo.info.age)
}
方案 | 优点 | 缺点 | 应用场景 |
---|---|---|---|
方案一:转成Record | 无须定义数据类 | 遇到嵌套类型数据处理麻烦 | 适用于只有基本类型场景 |
方案二:转成Object | 无须定义数据类 | 遇到嵌套类型数据处理麻烦 | 适用于只有基本类型场景 |
方案三:转成特定的类 | 嵌套类型数据处理简单 | 需要事先定义好数据类 | 适用于嵌套数据类型场景 |
【常见FAQ】
Q:params是否支持抽象类的传递? A:不支持,复杂的页面传参建议使用Navigation。
Q:params传递HashMap类型数据,目标页面无法获取到内容如何解决? A:router传递的参数会经过序列化,过程中会丢失方法。所以无法使用map,list传参。建议使用Navigation。
在HarmonyOS Next中使用Router传递自定义对象:
-
自定义类需实现Parcelable接口并重写marshalling/unmarshalling方法进行序列化
-
发送页面:
let parcelableData = new MyParcelableClass()
router.pushUrl({
url: 'pages/TargetPage',
params: { obj: parcelableData }
})
- 接收页面通过router.getParams()获取:
let receivedData = router.getParams()?.['obj'] as MyParcelableClass
注意传递的Parcelable对象大小限制为1MB。
在HarmonyOS Next中通过Router传递自定义对象,需要先将对象序列化为可传递的数据格式。以下是具体实现方法:
- 使用Parcelable接口序列化对象:
public class MyData implements Parcelable {
private String name;
private int age;
// 实现Parcelable接口方法
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(name);
dest.writeInt(age);
}
// 添加CREATOR
public static final Creator<MyData> CREATOR = new Creator<MyData>() {
@Override
public MyData createFromParcel(Parcel in) {
return new MyData(in);
}
};
}
- 传递对象:
// 发送方
Router router = Router.getInstance();
router.addParams("key", new MyParcelableData());
router.push(RouterPagePath.TARGET_PAGE);
// 接收方
MyData data = (MyData) getIntent().getParcelableExtra("key");
- 对于复杂对象,也可以使用JSON序列化:
// 发送方
Gson gson = new Gson();
String jsonData = gson.toJson(myObject);
router.addParams("key", jsonData);
// 接收方
String json = getIntent().getStringExtra("key");
MyObject obj = gson.fromJson(json, MyObject.class);
注意事项:
- 确保自定义类实现Parcelable接口
- 数据大小不超过1MB限制
- 复杂对象建议使用JSON序列化方式