文章目录一、引言二、V1版本PersistentStorage AppStorage2.1 简介2.2 登录与个人中心示例2.3 注意事项三、V2版本PersistenceV2 ObservedV2 Trace3.1 简介3.2 登录与个人中心示例3.3 注意事项四、V1与V2核心区别总结五、总结与选择建议一、引言在鸿蒙应用开发中数据持久化是构建完整应用体验的关键一环。无论是保存用户的登录状态、个人偏好还是缓存应用的核心数据都需要一套可靠且高效的持久化方案。随着HarmonyOS版本的演进数据持久化能力也从V1版本进化到了V2版本带来了更强大的功能和更灵活的使用方式。本文将深入对比V1PersistentStorageAppStorage和V2PersistenceV2ObservedV2Trace两种数据持久化方案并通过一个“登录与个人中心”示例带你掌握它们的核心用法、适用场景以及最佳实践。二、V1版本PersistentStorage AppStorage2.1 简介V1版本的持久化方案基于PersistentStorage和AppStorage的配合使用。PersistentStorage负责将选定的AppStorage属性持久化到磁盘并在应用重启时自动恢复。UI和业务逻辑不直接访问PersistentStorage所有属性访问都通过AppStorage进行两者之间是双向同步的关系。2.2 登录与个人中心示例下面通过一个登录与个人中心的示例展示V1版本的具体用法。1. 初始化持久化数据在EntryAbility中初始化需要持久化的属性。// 在UI实例初始化后调用onWindowStageCreate(windowStage:window.WindowStage):void{windowStage.loadContent(pages/Index,(err){// PersistentStorage必须在UI实例初始化成功后loadContent回调中调用// 早于此时机onCreate/aboutToAppear会导致持久化失效PersistentStorage.persistProp(isLogin,false);PersistentStorage.persistProp(userName,);PersistentStorage.persistProp(token,);});}2. 登录页面 - 保存登录状态使用StorageLink装饰器将UI变量与AppStorage中的属性绑定修改UI变量会自动同步到PersistentStorage。import{promptAction,router}fromkit.ArkUI;EntryComponentstruct LoginPage{StorageLink(isLogin)isLogin:booleanfalse;StorageLink(userName)userName:string;StorageLink(token)token:string;build(){Column({space:20}){Text(当前登录状态this.isLogin).fontSize(20)Button(个人中心).width(80%).onClick((){if(this.isLogin){router.push({url:pages/ProfilePage})}else{promptAction.showToast({message:未登录请先登录})}})Button(登录).width(80%).onClick((){// 模拟登录成功this.isLogintrue;this.userName张三;this.tokenabc123token;// 数据自动同步到PersistentStorage持久化router.push({url:pages/ProfilePage})})}.width(100%).height(100%).justifyContent(FlexAlign.Center)}}运行效果3. 个人中心页面 - 读取持久化数据同样使用StorageLink读取持久化的数据并在UI中展示。import{router}fromkit.ArkUI;EntryComponentstruct ProfilePage{StorageLink(isLogin)isLogin:booleanfalse;StorageLink(userName)userName:string;StorageLink(token)token:string;build(){Column({space:20}){if(this.isLogin){Text(用户名:${this.userName}).fontSize(20)Text(Token:${this.token}).fontSize(20)}else{Text(未登录).fontSize(20)}Button(返回).width(80%).onClick((){router.back()})}.width(100%).height(100%)}}运行效果2.3 注意事项调用时机PersistentStorage必须在UI实例初始化完成后调用否则持久化可能失败。类型限制仅支持number、string、boolean、enum、Map、Set、Date、undefined、null不支持嵌套对象。性能考量避免持久化大型数据集和频繁变化的变量否则会影响性能。存储路径存储路径为module级别不同module使用相同key时数据归属最先使用的module。三、V2版本PersistenceV2 ObservedV2 Trace3.1 简介V2版本引入了PersistenceV2单例对象配合ObservedV2和Trace装饰器实现了更强大、更灵活的持久化能力。通过connect或globalConnect绑定key修改被Trace装饰的属性时会自动触发持久化和UI更新。globalConnect从API 18开始支持存储路径为应用级别是推荐的使用方式。3.2 登录与个人中心示例1. 定义持久化数据模型使用ObservedV2装饰类并在需要持久化的属性上使用Trace装饰器。// src/main/ets/model/UserInfo.etsObservedV2exportclassUserInfo{TraceisLogin:booleanfalse;TraceuserName:string;Tracetoken:string;// 普通属性不会触发自动持久化lastLoginTime:string;}2. 登录页面 - 保存登录状态使用Local和PersistenceV2.connect获取持久化数据实例直接修改Trace属性即可。import{PersistenceV2}fromkit.ArkUI;import{UserInfo}from../model/UserInfo;importrouterfromohos.router;importpromptActionfromohos.promptAction;EntryComponentV2struct LoginPage{LocaluserInfo:UserInfoPersistenceV2.connect(UserInfo,userInfoKey,()newUserInfo())!;build(){Column({space:20}){Text(当前登录状态this.userInfo.isLogin).fontSize(20)Button(个人中心).width(80%).onClick((){if(this.userInfo.isLogin){router.push({url:pages/ProfilePage})}else{promptAction.showToast({message:未登录请先登录})}})Button(登录).width(80%).onClick((){// 直接修改Trace属性自动触发持久化和UI更新this.userInfo.isLogintrue;this.userInfo.userName张三;this.userInfo.tokenabc123token;// 注意lastLoginTime是普通属性不会自动持久化router.push({url:pages/ProfilePage})})}.width(100%).height(100%).justifyContent(FlexAlign.Center)}}运行效果3. 个人中心页面 - 读取持久化数据同样使用PersistenceV2.connect获取数据实例UI会自动响应Trace属性的变化。import{PersistenceV2}fromkit.ArkUI;import{UserInfo}from../model/UserInfo;importrouterfromohos.router;EntryComponentV2struct ProfilePage{LocaluserInfo:UserInfoPersistenceV2.connect(UserInfo,userInfoKey,()newUserInfo())!;build(){Column({space:20}){if(this.userInfo.isLogin){Text(用户名:${this.userInfo.userName}).fontSize(20)Text(Token:${this.userInfo.token}).fontSize(20)}else{Text(未登录).fontSize(20)}Button(返回).width(80%).onClick((){router.back()})}.width(100%).height(100%)}}运行效果4. 整体赋值场景当需要从服务器获取完整用户信息并整体赋值时需要注意V2的机制。// 方式一逐个属性赋值推荐constserverData{isLogin:true,userName:李四,token:newToken};this.userInfo.isLoginserverData.isLogin;this.userInfo.userNameserverData.userName;this.userInfo.tokenserverData.token;// 方式二先删除再重新连接适用于大量属性PersistenceV2.remove(userInfoKey);constnewUserInfonewUserInfo();newUserInfo.isLogintrue;newUserInfo.userName李四;newUserInfo.tokennewToken;// 重新connect获取新实例3.3 注意事项Trace装饰器只有被Trace装饰的属性变更才会触发自动持久化普通属性、V1状态变量、Observed对象的变化不会触发。整体赋值直接用新对象覆盖会导致持久化失效需要逐个属性赋值或先删除再重新connect。数据量控制不宜大量持久化数据可能导致页面卡顿。调用时机持久化操作需在UI实例初始化完成后调用loadContent回调触发后。API版本PersistenceV2从API 12开始支持globalConnect从API 18开始支持建议使用globalConnect应用级存储路径。四、V1与V2核心区别总结对比项V1 (PersistentStorage)V2 (PersistenceV2)数据模型仅支持基本类型不支持嵌套对象支持复杂对象需ObservedV2Trace触发持久化通过AppStorage属性变更自动同步仅Trace属性变更触发自动持久化存储路径module级别connect为module级globalConnect为应用级整体赋值直接赋值即可需逐个属性赋值或先删后建适用场景简单键值对存储复杂UI状态持久化性能适合小数据量不宜大量数据避免卡顿五、总结与选择建议V1方案简单、直接适合存储登录状态、用户偏好等简单的键值对数据。如果你的数据结构不复杂且不需要跨module共享V1是一个轻量级的选择。V2方案功能强大支持复杂对象和更精细的持久化控制。当你需要持久化复杂的UI状态、多页面共享状态或者希望获得更灵活的存储路径应用级时推荐使用V2的globalConnect。选择哪种方案取决于你的具体需求。对于大多数现代鸿蒙应用尤其是涉及复杂数据交互的场景V2方案是更优的选择。
鸿蒙应用开发:V1与V2版本数据持久化实战教程
文章目录一、引言二、V1版本PersistentStorage AppStorage2.1 简介2.2 登录与个人中心示例2.3 注意事项三、V2版本PersistenceV2 ObservedV2 Trace3.1 简介3.2 登录与个人中心示例3.3 注意事项四、V1与V2核心区别总结五、总结与选择建议一、引言在鸿蒙应用开发中数据持久化是构建完整应用体验的关键一环。无论是保存用户的登录状态、个人偏好还是缓存应用的核心数据都需要一套可靠且高效的持久化方案。随着HarmonyOS版本的演进数据持久化能力也从V1版本进化到了V2版本带来了更强大的功能和更灵活的使用方式。本文将深入对比V1PersistentStorageAppStorage和V2PersistenceV2ObservedV2Trace两种数据持久化方案并通过一个“登录与个人中心”示例带你掌握它们的核心用法、适用场景以及最佳实践。二、V1版本PersistentStorage AppStorage2.1 简介V1版本的持久化方案基于PersistentStorage和AppStorage的配合使用。PersistentStorage负责将选定的AppStorage属性持久化到磁盘并在应用重启时自动恢复。UI和业务逻辑不直接访问PersistentStorage所有属性访问都通过AppStorage进行两者之间是双向同步的关系。2.2 登录与个人中心示例下面通过一个登录与个人中心的示例展示V1版本的具体用法。1. 初始化持久化数据在EntryAbility中初始化需要持久化的属性。// 在UI实例初始化后调用onWindowStageCreate(windowStage:window.WindowStage):void{windowStage.loadContent(pages/Index,(err){// PersistentStorage必须在UI实例初始化成功后loadContent回调中调用// 早于此时机onCreate/aboutToAppear会导致持久化失效PersistentStorage.persistProp(isLogin,false);PersistentStorage.persistProp(userName,);PersistentStorage.persistProp(token,);});}2. 登录页面 - 保存登录状态使用StorageLink装饰器将UI变量与AppStorage中的属性绑定修改UI变量会自动同步到PersistentStorage。import{promptAction,router}fromkit.ArkUI;EntryComponentstruct LoginPage{StorageLink(isLogin)isLogin:booleanfalse;StorageLink(userName)userName:string;StorageLink(token)token:string;build(){Column({space:20}){Text(当前登录状态this.isLogin).fontSize(20)Button(个人中心).width(80%).onClick((){if(this.isLogin){router.push({url:pages/ProfilePage})}else{promptAction.showToast({message:未登录请先登录})}})Button(登录).width(80%).onClick((){// 模拟登录成功this.isLogintrue;this.userName张三;this.tokenabc123token;// 数据自动同步到PersistentStorage持久化router.push({url:pages/ProfilePage})})}.width(100%).height(100%).justifyContent(FlexAlign.Center)}}运行效果3. 个人中心页面 - 读取持久化数据同样使用StorageLink读取持久化的数据并在UI中展示。import{router}fromkit.ArkUI;EntryComponentstruct ProfilePage{StorageLink(isLogin)isLogin:booleanfalse;StorageLink(userName)userName:string;StorageLink(token)token:string;build(){Column({space:20}){if(this.isLogin){Text(用户名:${this.userName}).fontSize(20)Text(Token:${this.token}).fontSize(20)}else{Text(未登录).fontSize(20)}Button(返回).width(80%).onClick((){router.back()})}.width(100%).height(100%)}}运行效果2.3 注意事项调用时机PersistentStorage必须在UI实例初始化完成后调用否则持久化可能失败。类型限制仅支持number、string、boolean、enum、Map、Set、Date、undefined、null不支持嵌套对象。性能考量避免持久化大型数据集和频繁变化的变量否则会影响性能。存储路径存储路径为module级别不同module使用相同key时数据归属最先使用的module。三、V2版本PersistenceV2 ObservedV2 Trace3.1 简介V2版本引入了PersistenceV2单例对象配合ObservedV2和Trace装饰器实现了更强大、更灵活的持久化能力。通过connect或globalConnect绑定key修改被Trace装饰的属性时会自动触发持久化和UI更新。globalConnect从API 18开始支持存储路径为应用级别是推荐的使用方式。3.2 登录与个人中心示例1. 定义持久化数据模型使用ObservedV2装饰类并在需要持久化的属性上使用Trace装饰器。// src/main/ets/model/UserInfo.etsObservedV2exportclassUserInfo{TraceisLogin:booleanfalse;TraceuserName:string;Tracetoken:string;// 普通属性不会触发自动持久化lastLoginTime:string;}2. 登录页面 - 保存登录状态使用Local和PersistenceV2.connect获取持久化数据实例直接修改Trace属性即可。import{PersistenceV2}fromkit.ArkUI;import{UserInfo}from../model/UserInfo;importrouterfromohos.router;importpromptActionfromohos.promptAction;EntryComponentV2struct LoginPage{LocaluserInfo:UserInfoPersistenceV2.connect(UserInfo,userInfoKey,()newUserInfo())!;build(){Column({space:20}){Text(当前登录状态this.userInfo.isLogin).fontSize(20)Button(个人中心).width(80%).onClick((){if(this.userInfo.isLogin){router.push({url:pages/ProfilePage})}else{promptAction.showToast({message:未登录请先登录})}})Button(登录).width(80%).onClick((){// 直接修改Trace属性自动触发持久化和UI更新this.userInfo.isLogintrue;this.userInfo.userName张三;this.userInfo.tokenabc123token;// 注意lastLoginTime是普通属性不会自动持久化router.push({url:pages/ProfilePage})})}.width(100%).height(100%).justifyContent(FlexAlign.Center)}}运行效果3. 个人中心页面 - 读取持久化数据同样使用PersistenceV2.connect获取数据实例UI会自动响应Trace属性的变化。import{PersistenceV2}fromkit.ArkUI;import{UserInfo}from../model/UserInfo;importrouterfromohos.router;EntryComponentV2struct ProfilePage{LocaluserInfo:UserInfoPersistenceV2.connect(UserInfo,userInfoKey,()newUserInfo())!;build(){Column({space:20}){if(this.userInfo.isLogin){Text(用户名:${this.userInfo.userName}).fontSize(20)Text(Token:${this.userInfo.token}).fontSize(20)}else{Text(未登录).fontSize(20)}Button(返回).width(80%).onClick((){router.back()})}.width(100%).height(100%)}}运行效果4. 整体赋值场景当需要从服务器获取完整用户信息并整体赋值时需要注意V2的机制。// 方式一逐个属性赋值推荐constserverData{isLogin:true,userName:李四,token:newToken};this.userInfo.isLoginserverData.isLogin;this.userInfo.userNameserverData.userName;this.userInfo.tokenserverData.token;// 方式二先删除再重新连接适用于大量属性PersistenceV2.remove(userInfoKey);constnewUserInfonewUserInfo();newUserInfo.isLogintrue;newUserInfo.userName李四;newUserInfo.tokennewToken;// 重新connect获取新实例3.3 注意事项Trace装饰器只有被Trace装饰的属性变更才会触发自动持久化普通属性、V1状态变量、Observed对象的变化不会触发。整体赋值直接用新对象覆盖会导致持久化失效需要逐个属性赋值或先删除再重新connect。数据量控制不宜大量持久化数据可能导致页面卡顿。调用时机持久化操作需在UI实例初始化完成后调用loadContent回调触发后。API版本PersistenceV2从API 12开始支持globalConnect从API 18开始支持建议使用globalConnect应用级存储路径。四、V1与V2核心区别总结对比项V1 (PersistentStorage)V2 (PersistenceV2)数据模型仅支持基本类型不支持嵌套对象支持复杂对象需ObservedV2Trace触发持久化通过AppStorage属性变更自动同步仅Trace属性变更触发自动持久化存储路径module级别connect为module级globalConnect为应用级整体赋值直接赋值即可需逐个属性赋值或先删后建适用场景简单键值对存储复杂UI状态持久化性能适合小数据量不宜大量数据避免卡顿五、总结与选择建议V1方案简单、直接适合存储登录状态、用户偏好等简单的键值对数据。如果你的数据结构不复杂且不需要跨module共享V1是一个轻量级的选择。V2方案功能强大支持复杂对象和更精细的持久化控制。当你需要持久化复杂的UI状态、多页面共享状态或者希望获得更灵活的存储路径应用级时推荐使用V2的globalConnect。选择哪种方案取决于你的具体需求。对于大多数现代鸿蒙应用尤其是涉及复杂数据交互的场景V2方案是更优的选择。