鸿蒙 ArkUI V2 装饰器:AppStorageV2,应用级状态存取,告别 V1 的「set/get 手动同步」 写在前面如果你写过鸿蒙 ArkUI 应用大概率遇到过这个场景你写了个主题切换功能V1 用AppStorage.set(theme, dark)存应用级状态——结果改了之后 UI 不更新得手动this.theme AppStorage.get(theme)同步。你查文档发现 V1 的StorageLink/StorageProp能自动同步——但只能用在Component里V2 组件用不了。你查文档发现鸿蒙 6.1 给了 V2 的AppStorageV2——但点进去发现它没有set/get只有connect拿可观察对象。API 一脸懵。这是 V1「set/get 手动同步」和 V2「connect 拿可观察对象」的分水岭。鸿蒙 6.1 给的答案是AppStorageV2——connect(class, key, default)拿应用级可观察对象改成员就真触发 UI 重绘不用手动同步。本文就用一个真机可跑的「应用级主题/语言切换」demo把AppStorageV2从「听名字一脸懵」讲到「下个项目直接抄」。代码托管在 AtomGit文末有链接真机实拍截图作证。这是 V2 装饰器系列第二篇接续上篇 ObservedV2 Trace。适合人群写过鸿蒙应用、被 V1AppStorage手动同步折磨过的同学。不适合人群还在学State的同学——出门左转看我的入门篇。一、先讲清楚AppStorageV2 到底是啥一句话AppStorageV2 是鸿蒙 6.1 V2 应用级状态用 connect 拿可观察对象改成员就真重绘。V1 的AppStorage.set/get是键值对存取——改了不自动同步 UI要手动StorageLink或this.x AppStorage.get()。V2 的AppStorageV2.connect直接拿可观察对象ObservedV2Trace装的 class改成员就真触发 UI 重绘不用手动同步。核心 API 一览API作用一句话理解AppStorageV2.connect(type, key, default)拿应用级可观察对象「有就拿没有就用 default 新建」AppStorageV2.remove(key)删应用级键「清理应用级状态」AppStorageV2.keys()看所有应用级键「列出当前存了哪些」注意V2 没有set/get——这是跟 V1 最大的区别新手最容易踩的坑。二、动手一个应用级主题/语言切换的 demo2.1 定义 ObservedV2 class importimport{AppStorageV2}fromohos.arkui.StateManagementObservedV2classAppConfig{Tracetheme:stringlightTracelang:stringzh}三个细节import { AppStorageV2 } from ohos.arkui.StateManagement——V2 应用级状态需显式 import不是全局名ObservedV2 class AppConfig——应用级状态必须用ObservedV2class成员装TraceTrace theme/Trace lang——追踪这两个成员变化改了就触发 UI 重绘2.2 connect 拿应用级可观察对象EntryComponentV2struct Index{// connect 拿应用级可观察对象keyappConfig默认 new AppConfig()appCfg:AppConfigAppStorageV2.connect(AppConfig,appConfig,()newAppConfig())??newAppConfig()LocallogText:string(未操作)LocalopCount:number0build(){// ...}}connect三个关键点①connect(type, key, default)三参AppStorageV2.connect(AppConfig,// type: class 类型appConfig,// key: 应用级键名()newAppConfig()// defaultCreator: 默认值工厂)typeclass 类型告诉 AppStorageV2 存什么key应用级键名跨组件用同一个 key 拿同一个对象defaultCreator第一次 connect 时用这个工厂新建默认值②connect返回T | undefinedthis.appCfgAppStorageV2.connect(AppConfig,appConfig,()newAppConfig())??newAppConfig()connect可能返回undefined极端情况用?? new AppConfig()兜底。③ 跨组件用同一个 key 拿同一个对象// 组件 AappCfgAppStorageV2.connect(AppConfig,appConfig,()newAppConfig())// 组件 BappCfgAppStorageV2.connect(AppConfig,appConfig,()newAppConfig())// ← A 和 B 拿到的是同一个对象A 改 B 自动同步这是AppStorageV2最核心的能力——跨组件共享同一个可观察对象A 改成员 B 自动重绘。2.3 改成员 → UI 真重绘Button(改 theme darkTrace 触发重绘).width(92%).height(44).fontSize(14).onClick((){this.appCfg.themedark// ← 改成员UI 重绘this.opCountthis.logText第${this.opCount}次themedarkUI 重绘})这是 V2 最核心的能力——改this.appCfg.theme应用级可观察对象成员就真触发 UI 重绘。不用像 V1 那样AppStorage.set 手动同步。2.4 remove / keys 管理应用级状态Button(remove appConfigAppStorageV2.remove).onClick((){AppStorageV2.remove(appConfig)// ← 删应用级键})Button(keys() 看所有应用级键).onClick((){this.logTextkeys${JSON.stringify(AppStorageV2.keys())}// ← 列所有键})remove删应用级键keys列所有应用级键——管理用。三、真机实拍改成员真触发 UI 重绘我把这个 demo 装到真机上跑鸿蒙 6.1.1.125, API 24依次点改 themedark 改 langen下面两张都是真机实拍没有任何 P 图。初始态应用级状态themelight, langzh, opCount0 5 个按钮点改 themedark 改 langen 后themedark, langen, opCount2, 日志「第 2 次langenUI 重绘」重点看第二张theme 从 light 变成 dark、lang 从 zh 变成 en、opCount 从 0 变成 2——改应用级可观察对象成员就真触发了 UI 重绘不用手动同步。这是AppStorageV2.connectObservedV2Trace的真机证明。四、V2AppStorageV2vs V1AppStorage啥差异新手最容易纠结的问题既然 V1AppStorage那么标准鸿蒙为啥要造 V2维度V1AppStorageV2AppStorageV2import全局名import { AppStorageV2 } from ohos.arkui.StateManagement存取 APIset/get键值对connect拿可观察对象改成员触发重绘不触发要手动同步触发Trace 装的成员跨组件同步StorageLink/StorageProp同 key connect 同对象配套装饰ComponentStateComponentV2Local类型安全弱any强class 类型一句话决策新项目鸿蒙 6.1 用 V2改成员就重绘不用手动同步V1 项目维护老代码不动。五、常见坑都是血泪坑症状解法AppStorageV2.set/get编译报「没有 set 方法」V2 没有 set/get用connect拿可观察对象忘 importAppStorageV2编译报「Cannot find name AppStorageV2」import { AppStorageV2 } from ohos.arkui.StateManagementconnect忘装ObservedV2class改成员不触发重绘class 必须ObservedV2 成员Traceconnect返回 undefined 没兜底运行时 null 引用?? new AppConfig()兜底跨组件 key 不一致A 改 B 不同步跨组件用同一个 key用在 V1Component里编译报「V2 装饰器只能装在 ComponentV2」struct 改ComponentV2忘remove清理应用级状态泄漏不用了调AppStorageV2.remove(key)六、PersistenceV2持久化版应用级状态鸿蒙 6.1 还给了PersistenceV2——AppStorageV2的持久化版应用重启后状态还在import{PersistenceV2}fromohos.arkui.StateManagement// PersistenceV2.globalConnect(...) 持久化版 connect// PersistenceV2.save(key) 主动保存到磁盘API用途与 AppStorageV2 的区别AppStorageV2.connect应用生命周期内共享重启后丢PersistenceV2.globalConnect持久化到磁盘重启后还在PersistenceV2.save主动保存写磁盘场景决策主题/语言这种用户设置用PersistenceV2重启还在临时状态用AppStorageV2重启丢。七、完整代码仓库本文所有代码都已托管到AtomGit欢迎 clone、提 issue、点 star仓库地址https://atomgit.com/JaneConan/arkui-appstoragev2仓库包含完整的「AppStorageV2 应用级主题/语言切换」demo 工程Index.ets主页面import AppStorageV2ObservedV2class connect 改成员重绘 remove/keys跨组件共享同 key 的姿势说明可直接用 DevEco Studio 打开运行真机装普通应用必能跑八、下一步该学什么跑通这个 demo 之后你的 V2 应用级状态就入门了。这是 V2 装饰器系列第二篇后续按这个顺序往下ParamOnce下一篇V2 父子传参替代 V1PropLinkProviderConsumerV2 跨层传递替代 V1ProvideConsumeMonitorV2 监听变化替代 V1WatchComputedV2 计算属性自动派生PersistenceV2持久化版应用级状态重启还在写在最后AppStorageV2的本质是**「鸿蒙 6.1 给应用级状态 connect 拿可观察对象的原生机制」**——不是 V1 的「set/get 键值对」是 V2 专门给精细追踪的原生机制。代价是 import 多一行、connect三参多一步。一旦你开始用 V2 思维写应用级状态你会发现大部分「主题切换」「语言切换」「用户信息共享」「全局计数器」的需求都是AppStorageV2.connectObservedV2Trace的自然结果。代码量比 V1 手动同步少一半精细度高一倍。代码已经给你了仓库链接在上面。现在关掉这篇文章打开 DevEco Studio把 demo 跑起来亲手点改 theme 改 lang 感受下应用级状态自动同步。跑通了回来评论区打个「1」我看看有多少人真的动手了。作者JaneConan仓库https://atomgit.com/JaneConan/arkui-appstoragev2协议Apache-2.0随便用别告我