ArkTS 进阶之道23AppStorage 应用级状态边界——为啥所有页面共享状态页面卸载状态仍存在本文是「ArkTS 进阶之道」系列第 23 篇续「ArkUI 状态联动」深水区。上篇讲 Observed/ObjectLink 嵌套对象观测槽边界State 只观测一层嵌套对象子属性改不刷 UI。本文讲应用级状态边界AppStorage 应用级全局状态存储——根因在所有页面共享状态页面卸载状态仍存在。能力系列篇 23 讲过 AppStorage 怎么用本文讲为哈 AppStorage 应用级状态合法 State 页面级状态页面卸载就销毁——根因在应用级状态存储槽。一、开篇AppStorage 不是页面级 State是应用级全局状态存储你写 React 时应用级状态是「Context 魔法」createContext Provider 全局// React 应用级状态Context Provider const AppContext createContext({ count: 0 }) function App() { return AppContext.Provider value{{ count: 0 }}Page //AppContext.Provider } function Page() { const { count } useContext(AppContext) // 应用级 Context 全局 return Textcount{count}/Text } // React 应用级状态Context Provider全局魔法你写鸿蒙 ArkTS 时AppStorage应用级全局状态存储——所有页面共享// ArkTS AppStorage 应用级全局状态存储 AppStorage.setOrCreate(appCount, 0) // ✅ 初始化 AppStorage 键应用级全局状态 Entry Component struct Index { StorageLink(appCount) appCount: number 0 // ✅ StorageLink 双向绑定 AppStorage 键 build() { Button(appCount${this.appCount}) .onClick(() { this.appCount }) // ✅ StorageLink 改 → AppStorage 同步 → 其他页面同步 } } // AppStorage 应用级全局状态所有页面共享页面卸载状态仍存在Context 魔法 vs 应用级状态存储槽的区别React 把应用级状态当 Context 魔法createContext Provider 全局ArkTS 把 AppStorage 当「应用级状态存储槽」所有页面共享页面卸载状态仍存在。根因不是 Context 魔法是应用级状态存储槽——AppStorage 应用级全局状态存储所有页面共享页面卸载状态仍存在。二、根因AppStorage 的应用级状态存储槽机制鸿蒙 ArkUI 的 AppStorage 是应用级状态存储槽绑定——所有页面共享页面卸载状态仍存在来自三重绑定机制。机制 1AppStorage 应用级全局状态存储——不是页面级 StateAppStorage 荬饰器应用级全局状态存储——所有页面共享页面卸载状态仍存在// ✅ 初始化 AppStorage应用级全局状态 AppStorage.setOrCreate(appCount, 0) AppStorage.setOrCreate(appTheme, #007DFF) Entry Component struct Index { StorageLink(appCount) appCount: number 0 // ✅ StorageLink 双向绑定 AppStorage 键 build() { Column() { Text(appCount ${this.appCount}) Button(改 appCount) .onClick(() { this.appCount }) // ✅ StorageLink 改 → AppStorage 同步 → 其他页面同步 } } } // AppStorage 应用级全局状态所有页面共享页面卸载状态仍存在不用重新初始化应用级全局状态存储AppStorageappCount应用级全局状态存储——所有页面共享appCount页面卸载状态仍存在不用重新初始化。根因不是页面级 State 是应用级状态存储槽——AppStorage 应用级全局状态存储所有页面共享页面卸载状态仍存在。机制 2StorageLink 双向绑定 AppStorage 键——改 Storage 同步其他页面StorageLink 荬饰器双向绑定 AppStorage 键——改 StorageLink → AppStorage 同步 → 其他页面同步Entry Component struct Index { StorageLink(appCount) appCount: number 0 // ✅ StorageLink 双向绑定 AppStorage 键 StorageLink(appTheme) appTheme: string #007DFF // ✅ StorageLink 双向绑定 AppStorage 键 build() { Column() { Text(appCount ${this.appCount}).fontColor(this.appTheme) Button(改 appCount) .onClick(() { this.appCount }) // ✅ StorageLink 改 → AppStorage 同步 → 其他页面同步 Button(改 appTheme红色) .onClick(() { this.appTheme #FF4D4F }) // ✅ StorageLink 改 → AppStorage 同同步 } } } // StorageLink 双向绑定 AppStorage 键改 → AppStorage 同步 → 其他页面 StorageLink 同步双向StorageLink 双向绑定 AppStorage 键StorageLinkappCount荬饰器双向绑定 AppStorage 键——改appCount→ AppStorage 同步 → 其他页面StorageLink同步双向。根因不是页面级状态是应用级状态存储槽——StorageLink 双向绑定 AppStorage 键改 → AppStorage 同步 → 其他页面同步双向。机制 3AppStorage.set 直接改应用级状态——不用 StorageLink 也能改AppStorage.set直接改应用级状态——不用 StorageLink 也能改StorageLink 自动同步Entry Component struct Index { StorageLink(appCount) appCount: number 0 // ✅ StorageLink 双向绑定 AppStorage 键 build() { Column() { Text(appCount ${this.appCount}) Button(直接改 AppStorage.set(appCount, 100)) .onClick(() { AppStorage.set(appCount, 100) // ✅ AppStorage.set 直接改应用级状态 // ✅ StorageLink appCount 自动同步StorageLink 绑定 AppStorage 键 }) } } } // AppStorage.set 直接改应用级状态不用 StorageLink 也能改StorageLink 自动同步AppStorage.set 直接改应用级状态AppStorage.setappCount直接改应用级状态——不用 StorageLink 也能改StorageLinkappCount自动同步StorageLink 绑定 AppStorage 键。根因不是必须用 StorageLink 是 AppStorage.set 直接改——AppStorage.set 直接改应用级状态StorageLink 自动同步。机制 4AppStorage vs State 页面级状态边界——应用级 vs 页面级AppStorage应用级全局状态所有页面共享页面卸载状态仍存在State页面级状态页面卸载就销毁——根因都是状态存储但绑的机制不同// ✅ AppStorage 路径应用级全局状态所有页面共享页面卸载状态仍存在 AppStorage.setOrCreate(appCount, 0) Entry Component struct Page1 { StorageLink(appCount) appCount: number 0 // ✅ StorageLink 双向绑定 AppStorage 键 build() { Button(Page1 appCount${this.appCount}).onClick(() { this.appCount }) } } Entry Component struct Page2 { StorageLink(appCount) appCount: number 0 // ✅ Page2 也绑定同一个 AppStorage 键 build() { Button(Page2 appCount${this.appCount}).onClick(() { this.appCount }) } } // ✅ AppStorage 应用级全局状态Page1 改 appCount → Page2 同步所有页面共享 // ⚠ State 路径页面级状态页面卸载就销毁 Entry Component struct Page3 { State pageCount: number 0 // ⚠ State 页面级状态页面卸载就销毁 build() { Button(Page3 pageCount${this.pageCount}).onClick(() { this.pageCount }) } } // ⚠ State 页面级状态Page3 卸载 pageCount 销毁不共享不持久AppStorage vs State 页面级状态边界AppStorage 路径——应用级全局状态所有页面共享页面卸载状态仍存在推荐跨页面状态。State 路径——页面级状态页面卸载就销毁单页面状态。根因都是状态存储但绑的机制不同——AppStorage 应用级全局状态存储槽所有页面共享State 页面级状态页面卸载就销毁。三、真机配图AppStorage 应用级状态边界——所有页面共享状态初始态appCount0、appTheme“#007DFF” 蝔色文字均应用级状态初始态齐点调三按钮后appCount100 被 AppStorage.set 直接改 100 覆盖、appTheme“#FF4D4F” 红色文字、AppStorage 应用级状态同步证据齐对比证据点改 appCount 按钮后 appCount 同步StorageLink 双向同步点改 appTheme红色按钮后 appTheme“#FF4D4F” 红色文字同步点直接改 AppStorage.set(“appCount”, 100) 按钮后 appCount100 被 AppStorage.set 直接改 100 覆盖StorageLink 自动同步。AppStorage 应用级全局状态——所有页面共享页面卸载状态仍存在StorageLink 双向绑定 AppStorage 键AppStorage.set 直接改应用级状态 StorageID 自动同步。四、真解法AppStorage 应用级状态的三个场景场景 1AppStorage 应用级计数器90% 场景首选应用级状态存储槽AppStorage.setOrCreate(appCount, 0) Entry Component struct Index { StorageLink(appCount) appCount: number 0 // ✅ StorageLink 双向绑定 AppStorage 键 build() { Column() { Text(appCount ${this.appCount}) Button(改 appCount) .onClick(() { this.appCount }) // ✅ StorageLink 改 → AppStorage 同步 → 其他页面同步 } } }为哈能跑AppStorage 应用级计数器——应用级状态存储槽AppStorageappCount应用级全局状态StorageLink 双向绑定 AppStorage 键改appCount→ AppStorage 同步 → 其他页面同步双向。首选这个90% 的场景应用级跨页面状态用 AppStorage 应用级状态存储槽就够。要写「应用级跨页面状态计数器等」时用这个——不用 State 页面级状态页面卸载就销毁AppStorage 应用级状态存储槽所有页面共享。场景 2AppStorage 应用级主题色应用级状态存储槽所有页面共享主题AppStorage.setOrCreate(appTheme, #007DFF) Entry Component struct Index { StorageLink(appTheme) appTheme: string #007DFF // ✅ StorageLink 双向绑定 AppStorage 键 build() { Column() { Text(appTheme ${this.appTheme}).fontColor(this.appTheme) Button(改 appTheme红色) .onClick(() { this.appTheme #FF4D4F }) // ✅ StorageLink 改 → AppStorage 同步 → 其他页面同步 } } } // AppStorage 应用级主题色所有页面共享 appTheme改 → AppStorage 同步 → 其他页面同步为哈能跑AppStorage 应用级主题色——应用级状态存储槽AppStorageappTheme应用级全局状态StorageLink 双向绑定 AppStorage 键改appTheme→ AppStorage 同步 → 其他页面同步双向。要写「应用级跨页面主题主题色等」时用这个——不用 State 页面级状态页面卸载就销毁AppStorage 应用级状态存储槽所有页面共享主题。场景 3AppStorage.set 直接改应用级状态不用 StorageLink 也能改AppStorage.setOrCreate(appCount, 0) Entry Component struct Index { StorageLink(appCount) appCount: number 0 // ✅ StorageLink 双向绑定 AppStorage 键 build() { Column() { Text(appCount ${this.appCount}) Button(直接改 AppStorage.set(appCount, 100)) .onClick(() { AppStorage.set(appCount, 100) // ✅ AppStorage.set 直接改应用级状态 // ✅ StorageLink appCount 自动同步StorageLink 绑定 AppStorage 键 }) } } } // AppStorage.set 直接改应用级状态不用 StorageLink 也能改StorageLink 自动同步为哈能跑AppStorage.set 直接改应用级状态——应用级状态存储槽AppStorage.setappCount直接改应用级状态StorageLinkappCount自动同步StorageLink 绑定 AppStorage 键。要写「直接改应用级状态不用 StorageLink 也能改等」时用这个——不用 StorageLink 也能改AppStorage.set 直接改应用级状态 StorageLink 自动同步。五、一句话哲学AppStorage 不是页面级 State是应用级全局状态存储槽的所有页面共享。ArkUI 的 AppStorage 荬饰器应用级全局状态存储所有页面共享页面卸载状态仍存在。根因不是页面级 State 是应用级状态存储槽——AppStorage 应用级全局状态存储所有页面共享页面卸载状态仍存在 StorageLink 双向绑定 AppStorage 键改 → AppStorage 同步 → 其他页面同步双向 AppStorage.set 直接改应用级状态不用 StorageLink 也能改 StorageLink 自动同步 AppStorage vs State 页面级状态边界应用级 vs 页面级。对比 React 应用级状态 Context 魔法createContext Provider 全局ArkTS AppStorage 应用级状态存储槽所有页面共享。状态联动深水区串讲Watch 绑 State 变触发副作用回调槽篇 68 Link $ 语法双向绑定跨组件同步篇 69 Provide/Consume 跨层级传递槽祖辈后辈同步篇 70 Observed/ObjectLink 嵌套对象观测槽子属性改刷 UI篇 71 AppStorage 应用级状态存储槽所有页面共享篇 72State 页面级状态页面卸载就销毁——续「ArkUI 状态联动」深水区讲状态联动深水区Watch 副作用回调槽边界 Link $ 语法双向绑定边界 Provide/Consume 跨层级传递槽边界 Observed/ObjectLink 嵌套对象观测槽边界 AppStorage 应用级状态存储槽边界。系列预告下篇篇 73讲 LocalStorage 页面级状态边界页面级局部状态根因续「ArkUI 状态联动」深水区。五阶段哲学体系类型哲学50-52→ 作用域哲学53-55→ 状态哲学56-59→ 渎染哲学60-62→ 组件设计63-67→ 状态联动深水区68讲清 ArkTS/ArkUI 进阶哲学。能力系列回链能力系列篇本文进阶点篇 23 AppStorage 用法AppStorage 应用级状态存储槽边界根因所有页面共享页面卸载状态仍存在篇 13 State 基础用法状态哲学State 赋值就刷 UI 依赖追踪篇 59 Watch 用法状态联动深水区Watch 副作用回调槽 vs onClick 直接调副作用边界真机 demo 完整代码// 篇 72 demoAppStorage 应用级状态边界 // AppStorage 应用级全局状态所有页面共享页面卸载状态仍存在 // StorageLink/StorageProp 绑定 AppStorage 键 // ✅ 初始化 AppStorage应用级全局状态 AppStorage.setOrCreate(appCount, 0) AppStorage.setOrCreate(appTheme, #007DFF) Entry Component struct Index { // ✅ StorageLink 双向绑定 AppStorage 键应用级全局状态 StorageLink(appCount) appCount: number 0 StorageLink(appTheme) appTheme: string #007DFF State log: string (未操作) build() { Column({ space: 12 }) { Text(篇 72 配图AppStorage 应用级状态边界) .fontSize(16).fontWeight(FontWeight.Bold).margin({ top: 16, bottom: 4 }) Text(AppStorage 应用级全局状态所有页面共享页面卸载状态仍存在) .fontSize(11).fontColor(#888).margin({ bottom: 8 }) // ✅ 应用级状态展示 Column({ space: 6 }) { Text(应用级全局状态AppStorage) .fontSize(12).fontColor(#2563eb).fontWeight(FontWeight.Bold) Text(appCount ${this.appCount}) .fontSize(15).fontWeight(FontWeight.Bold).fontColor(#2563eb) Text(appTheme ${this.appTheme}) .fontSize(13).fontColor(this.appTheme) } .width(92%).padding(10).backgroundColor(#e0f0ff).borderRadius(8) // ✅ 改 AppStorage 键StorageLink 双向同步 Button(改 appCountStorageLink 双向同步) .width(92%).height(40).fontSize(12) .onClick(() { this.appCount // ✅ StorageLink 改 → AppStorage 同步 → 其他页面同步 this.log 改 appCount${this.appCount}AppStorage 应用级状态 }) Button(改 appTheme红色StorageLink 双向同步) .width(92%).height(40).fontSize(12) .onClick(() { this.appTheme #FF4D4F // ✅ StorageLink 改 → AppStorage 同步 this.log 改 appTheme红色AppStorage 应用级状态 }) // ✅ 直接改 AppStorage不用 StorageLinkAppStorage.set 直接改 Button(直接改 AppStorage.set(appCount, 100)) .width(92%).height(40).fontSize(12) .onClick(() { AppStorage.set(appCount, 100) // ✅ AppStorage.set → StorageLink 同步 this.log 直接改 AppStorage.set appCount100StorageLink 同步 }) Text(日志${this.log}).fontSize(10).fontColor(#333).margin({ top: 4 }) } .width(100%).height(100%).alignItems(HorizontalAlign.Center) } }写鸿蒙 ArkUI 记住AppStorage 不是页面级 State 是应用级全局状态存储槽的所有页面共享——AppStorage 荬饰器应用级全局状态存储所有页面共享页面卸载状态仍存在。根因不是页面级 State 是应用级状态存储槽——AppStorage 应用级全局状态存储所有页面共享页面卸载状态仍存在 StorageLink 双向绑定 AppStorage 键改 → AppStorage 同步 → 其他页面同步双向 AppStorage.set 直接改应用级状态不用 StorageLink 也能改 StorageLink 自动同步 AppStorage vs State 页面级状态边界应用级 vs 页面级。AppStorage 应用级计数器用应用级状态存储槽首选90% 场景AppStorage 应用级主题色用应用级状态存储槽所有页面共享主题AppStorage.set 直接改应用级状态不用 StorageLink 也能改 StorageLink 自动同步。应用级状态存储槽所有页面共享页面卸载状态仍存在是 ArkUI 状态联动深水区核心