HarmonyOS 鸿蒙Next中关于ObservedV2对象的序列化和反序列化的问题
HarmonyOS 鸿蒙Next中关于ObservedV2对象的序列化和反序列化的问题
ObservedV2序列化和反序列化的使用限制
- @ObservedV2的类实例目前不支持使用JSON.stringify进行序列化。
- 使用@ObservedV2与@Trace装饰器的类,需通过new操作符实例化后,才具备被观测变化的能力。
以上描述来自官方文档
提出需求
- @ObservedV2的类实例可以序列化为json字符串
- json字符串可以反序列化为@ObservedV2的类实例,并具备被观测变化的能力
- 支持嵌套的可序列化和反序列化
@ObservedV2的类实例序列化为json字符串
方案一:JSON.stringify(obj).replaceAll(’_ob’,’’)
[@ObservedV2](/user/ObservedV2)
export class Contact{
[@Trace](/user/Trace) name:string
[@Trace](/user/Trace) value:string
constructor(name: string, value: string) {
this.name = name;
this.value = value;
}
}
[@ObservedV2](/user/ObservedV2)
export class User {
[@Trace](/user/Trace)
username: string
[@Trace](/user/Trace)
age: number
[@Trace](/user/Trace)
contacts:Contact[]
constructor(username: string,age:number,contacts:Contact[]) {
this.username = username;
this.age = age;
this.contacts = contacts
}
}
把User对象序列化为json字符串
function userStringify(){
let contacts:Contact[] = [new Contact('phone','123456')]
let user:User = new User('alice',2.5,contacts)
let jsonStr = JSON.stringify(user).replaceAll('__ob_','')
Logger.debug(jsonStr)
}
日志打印结果:
{"username":"alice","age":2.5,"contacts":[{"name":"phone","value":"123456"}]}
方案二:使用class-transformer库序列化@ObservedV2对象
安装class-transformer
ohpm install class-transformer@0.5.1
直接序列化输出的数据错误,属性名称都变成__ob_xx
let jsonStr = JSON.stringify(instanceToPlain(user))
//日志打印结果
{"__ob_username":"alice","__ob_age":2.5,"__ob_contacts":[{"__ob_name":"phone","__ob_value":"123456"}]}
import {instanceToPlain,Expose} from 'class-transformer';
[@ObservedV2](/user/ObservedV2)
export class Contact{
[@Expose](/user/Expose)()
[@Trace](/user/Trace)
name:string
[@Expose](/user/Expose)()
[@Trace](/user/Trace)
value:string
constructor(name: string, value: string) {
this.name = name;
this.value = value;
}
}
[@ObservedV2](/user/ObservedV2)
export class User {
[@Expose](/user/Expose)()
[@Trace](/user/Trace)
username: string
[@Expose](/user/Expose)()
[@Trace](/user/Trace)
age: number
[@Expose](/user/Expose)()
[@Trace](/user/Trace)
contacts:Contact[]
constructor(username: string,age:number,contacts:Contact[]) {
this.username = username;
this.age = age;
this.contacts = contacts
}
}
function userStringifyPlayB(){
let contacts:Contact[] = [new Contact('phone','123456')]
let user:User = new User('alice',2.5,contacts)
//排除掉__ob_前缀的字段
let jsonStr = JSON.stringify(instanceToPlain(user,{ excludePrefixes:['__ob_']}))
Logger.debug(jsonStr)
}
日志打印结果:
{"username":"alice","age":2.5,"contacts":[{"name":"phone","value":"123456"}]}
ObservedV2的反序列化可移步我写的这一篇文章
[如何让从Http请求返回的JSON数据转换为@ObservedV2、@Trace装饰的类的对象具有触发UI刷新的能力](https://developer.huawei.com/consumer/cn/forum/topic/0204187019579771145?fid=0109140870620153026)
更多关于HarmonyOS 鸿蒙Next中关于ObservedV2对象的序列化和反序列化的问题的实战教程也可以访问 https://www.itying.com/category-93-b0.html
//排除掉__ob_前缀的字段
let jsonStr = JSON.stringify(instanceToPlain(user,{strategy:'excludeAll'}))
这样也可以
更多关于HarmonyOS 鸿蒙Next中关于ObservedV2对象的序列化和反序列化的问题的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
👍 {excludeExtrueousValues:true} 或者 {strategy:'excludeAll'} 都可以,但是需要注意的一点是 ObservedV2 装饰的类的所有属性都要加 @Expose 装饰器,不然序列化后的数据没有该属性,考虑到这一点这里就用的 { excludePrefixes:['__ob_']}。
当然如果 class 定义的属性名称类似这样的 __ob_id:number 就应该用你这种方式了。
🤣,
在HarmonyOS鸿蒙Next中,ObservedV2对象支持序列化和反序列化操作。序列化通过@ObservedV2装饰器的属性转换机制实现,将对象状态转换为可存储格式。反序列化时,系统自动重建对象状态并恢复响应式绑定。需使用ArkTS的序列化API,如JSON.stringify()和JSON.parse(),结合ObservedV2的特定方法处理装饰器属性。注意避免直接操作非公开接口,确保数据一致性。
针对ObservedV2对象的序列化问题,你提供的两种方案都很实用。
方案一使用字符串替换简单直接,适合简单场景,但需要注意可能误删其他字段中的"_ob"字符串。
方案二使用class-transformer库更为规范,通过@Expose装饰器明确指定需要序列化的属性,配合excludePrefixes选项过滤内部字段,代码可维护性更好。
对于反序列化需求,你提到的文章提供了完整解决方案,通过plainToInstance结合自定义实例化逻辑,确保反序列化后的对象保持响应式能力。
这两种方案都能满足嵌套序列化需求,建议根据项目复杂度选择:小型项目可用方案一,大型项目推荐方案二配合完整的序列化/反序列化流程。

