【共创季稿事节】鸿蒙原生 ArkTS 布局方式之 @StorageProp 持久化布局:App 级别状态持久化完全指南
一、引言在 HarmonyOS 应用开发中状态管理 是构建流畅、可维护 UI 的核心挑战之一。当用户在一个页面切换了主题色跳转到另一个页面后颜色却恢复了默认 —— 这种体验显然不够原生。鸿蒙 ArkTS 提供了三层级的状态管理方案层级 存储方案 生命周期 适用场景组件级 State / Prop 组件销毁即释放 局部 UI 状态页面级 LocalStorage / LocalStorageProp 页面销毁即释放 页面内的临时偏好应用级 AppStorage / StorageProp / StorageLink 应用进程级别 全局主题、用户信息本文将围绕 应用级持久化 这一主题深入剖析 StorageProp LocalStorage AppStorage 三者的配合方式并通过一个完整的主题配置 Demo 展示其工程落地。二、三者的角色与关系2.1 AppStorage — 应用的全局数据中心AppStorage 是一个 应用级单例所有 UIAbility 和 Page 共享同一份数据。它的核心特征全局唯一 整个进程中只有一个 AppStorage 实例响应式 任何一方修改数据所有绑定该 key 的 UI 自动刷新进程级生命周期 数据随应用进程存在即使用户从 A 页面跳转到 B 页面再返回状态保持不变⚠️ 注意 AppStorage 仅在应用进程存活期间有效。进程被系统回收后数据会丢失。如需永久持久化跨进程重启应配合 PersistentStorage 使用。2.2 StorageProp — 组件的AppStorage 窗口StorageProp(key) 将组件属性与 AppStorage 中指定 key 建立 单向同步 组件可写 的关系┌──────────────┐ 读/写 ┌──────────────────┐│ 组件属性 │ ◄─────────► │ AppStorage(key) ││ StorageProp │ └──────────────────┘└──────────────┘组件初始化时从 AppStorage 读取对应 key 的值组件内修改该属性自动写回 AppStorage其他绑定了同一 key 的组件自动收到变更通知并刷新与 StorageLink 的区别StorageLink 是双向同步且会覆盖本地默认值StorageProp 优先使用 AppStorage 的值若 key 不存在则使用组件声明的默认值。2.3 LocalStorage 与 LocalStorageProp — 页面的临时工作台LocalStorage 是 页面级存储生命周期与页面一致┌─────────────────────────┐│ Page A ││ ┌───────────────────┐ ││ │ LocalStorage │ │ ← 仅 Page A 可见│ │ LocalStorageProp │ ││ └───────────────────┘ │└─────────────────────────┘页面销毁时LocalStorage 自动释放无需手动清理适合存储仅当前页面需要的临时状态如表单草稿、滚动位置LocalStorageProp 绑定方式与 StorageProp 完全一致只是数据源不同2.4 三者的协作关系图┌─────────────────────────────────────────────────┐│ 应用进程 ││ ││ ┌──────────┐ AppStorage ┌──────────┐ ││ │ Page A │ ◄──────────► │ Page B │ ││ │ StorageProp │ │ StorageProp │ ││ │ LocalStorage │ │ │ ││ └──────────┘ └──────────┘ ││ │ ││ │ LocalStorage页面级 ││ ▼ ││ ┌──────────┐ ││ │ Component│ ││ │ State │ ││ └──────────┘ │└─────────────────────────────────────────────────┘三、Demo 项目架构解析3.1 项目结构entry/src/main/ets/├── entryability/│ └── EntryAbility.ets ← AppStorage 初始化入口└── pages/├── Index.ets ← 首页含导航按钮└── StoragePropDemo.ets ← 持久化布局演示页435行3.2 应用启动时的数据初始化在 EntryAbility.ets 的 onCreate 中我们通过 AppStorage.SetOrCreate() 预置了 4 个全局 key// EntryAbility.ets — 应用级数据预置onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {// …AppStorage.SetOrCreate(‘themeColor’, ‘#007AFF’);AppStorage.SetOrCreate(‘fontSize’, 16);AppStorage.SetOrCreate(‘isDarkMode’, false);AppStorage.SetOrCreate(‘userName’, ‘HarmonyOS 用户’);}SetOrCreate 的语义是如果 key 不存在则创建并赋值已存在则忽略。这使得首次安装时使用代码中的默认值后续启动时保留用户上次修改的值配合 PersistentStorage 可实现永久保持⚠️ HarmonyOS NEXT 注意 SetOrCreate 在新版 SDK 中已标记为废弃推荐使用 AppStorage.setOrCreate() 替代驼峰命名。Demo 代码中仍保留旧 API 以兼容 API 12 以下版本。3.3 页面模块级别的 AppStorage 初始化除了在 EntryAbility 中初始化演示页 StoragePropDemo.ets 在文件模块作用域也做了一次相同的初始化// StoragePropDemo.ets — 文件模块级初始化AppStorage.SetOrCreate(‘themeColor’, ‘#007AFF’);AppStorage.SetOrCreate(‘fontSize’, 16);AppStorage.SetOrCreate(‘isDarkMode’, false);AppStorage.SetOrCreate(‘userName’, ‘HarmonyOS 用户’);这是一种 防御性初始化策略即使 EntryAbility 的初始化因某些原因延迟或失败页面被加载时也能确保 AppStorage 中的 key 已就绪。这是编写健壮的鸿蒙应用的一个重要技巧。3.4 组件中的 StorageProp 声明EntryComponentstruct StoragePropDemo {// ---- AppStorage 绑定 ----StorageProp(‘themeColor’) themeColor: string ‘#007AFF’;StorageProp(‘fontSize’) fontSize: number 16;StorageProp(‘isDarkMode’) isDarkMode: boolean false;StorageProp(‘userName’) userName: string ‘HarmonyOS 用户’;// ---- LocalStorage 绑定 ----LocalStorageProp(‘pageTitle’) pageTitle: string ‘AppStorage 持久化布局演示’;// ---- 组件级状态 ----State currentColorIndex: number 0;}关键区分themeColor、fontSize、isDarkMode、userName 使用 StorageProp — 它们在所有页面间共享pageTitle 使用 LocalStorageProp — 它只在这个页面有效currentColorIndex 使用 State — 纯组件局部状态仅用于 UI 交互记录四、六大交互模块逐行解读4.1 状态总览 — 读操作的演示BuilderbuildStatusOverview() {Column({ space: 8 }) {this.buildInfoRow(‘主题色’, this.themeColor)this.buildInfoRow(‘字体大小’, this.fontSize ‘fp’)this.buildInfoRow(‘暗黑模式’, this.isDarkMode ? ‘已开启’ : ‘已关闭’)this.buildInfoRow(‘用户名’, this.userName)}}要点 这是最简单的使用场景 —— 读取 AppStorage 中的值。所有 4 个 StorageProp 变量被直接用于 UI 展示无需手动从 AppStorage 取值。4.2 主题色选择器 — 写入并触发联动BuilderbuildColorPicker() {// …ForEach(COLOR_PRESETS, (color: string) {Circle().width(40).height(40).fill(color).onClick(() {this.themeColor color; // ← 这一行是关键promptAction.showToast({message: 主题色已切换为 ’ color});})if (this.themeColor color) {// 显示选中标记}})}数据流 onClick → this.themeColor color → AppStorage(‘themeColor’) 更新 → 所有绑定组件刷新选中标记通过 if (this.themeColor color) 条件渲染这是响应式编程的典型模式状态驱动 UI而非命令式修改 UI。4.3 字体大小滑块 — 连续写入Slider({value: this.fontSize, min: 12, max: 24, step: 1}).onChange((value: number) {this.fontSize value; // 每次拖动都写回 AppStorage})要点 滑块拖动产生的连续事件每一次都会触发 StorageProp 的写入。由于 StorageProp 的底层实现是高效的脏检查机制这种高频写入不会造成性能问题。4.4 暗黑模式开关 — Toggle 组件联动Toggle({ type: ToggleType.Switch, isOn: this.isDarkMode }).onChange((isOn: boolean) {this.isDarkMode isOn;promptAction.showToast({message: isOn ? ‘已切换到暗黑模式’ : ‘已切换到亮色模式’});})整体 UI 响应 暗黑模式不仅仅改变 Toggle 本身的状态整个页面的背景色、文字颜色、卡片颜色全部随之变化 —— 因为它们都读取了 this.isDarkMode.backgroundColor(this.isDarkMode ? ‘#1A1A1A’ : ‘#FFFFFF’)// 每个 Card:.bgColor(this.isDarkMode ? ‘#2C2C2C’ : ‘#F5F5F7’)// 每个 Text:.fontColor(this.isDarkMode ? ‘#CCCCCC’ : ‘#666666’)这就是 响应式持久化布局 的核心优势一处修改全局联动。4.5 用户名编辑 — TextInput 双向绑定TextInput({ placeholder: ‘请输入用户名’, text: this.userName }).onChange((value: string) {this.userName value; // 写回 AppStorage})要点 用户在输入框中键入的每个字符都会实时同步到 AppStorage。当用户跳转到其他页面时其他页面通过同名 StorageProp(‘userName’) 读取到最新的值。4.6 ✨ 实时效果预览 — 综合展示BuilderbuildPreviewPane() {Column({ space: 8 }) {Text(Hello, ’ this.userName ‘!’).fontSize(this.fontSize) // 从 AppStorage 读取字号.fontColor(this.themeColor) // 从 AppStorage 读取颜色.fontWeight(FontWeight.Bold)}.border({ width: 2, color: this.themeColor }) // 边框颜色跟随主题}这一区域集成了所有 4 个 StorageProp 变量形成一个 实时预览面板让用户直观地看到所有设置的综合效果。五、BuilderParam 组件复用模式Demo 中抽取了一个可复用的 Card 组件展示了鸿蒙中 组件插槽Slot 的实现方式Componentstruct Card {Prop title: string ‘’;BuilderParam content: () void this.emptyContent;Prop bgColor: string ‘#F5F5F7’;Builder emptyContent() {} build() { Column() { Text(this.title) .fontSize(16).fontWeight(FontWeight.Bold) .fontColor(#1A1A1A).margin({ bottom: 12 }) .width(100%) this.content() // ← BuilderParam 占位, 由父组件填充 } .width(100%).padding(16) .backgroundColor(this.bgColor) .borderRadius(12).margin({ bottom: 12 }) }}父组件通过 尾随闭包 传入内容Card({ title: ‘ 主题色’, bgColor: ‘#F5F5F7’ }) {this.buildColorPicker() // ← 闭包内容自动赋值给 BuilderParam content}这种模式的优势关注点分离 Card 只负责容器样式内容由调用方决定高复用性 一个 Card 组件可以承载任何 Builder 内容类型安全 编译期即检查闭包是否符合 () void 签名六、生命周期与数据流深度剖析6.1 StorageProp 的完整生命周期应用启动│▼AppStorage.SetOrCreate(‘themeColor’, ‘#007AFF’) ← 初始化│▼StorageProp(‘themeColor’) themeColor: string ← 组件读取│▼用户在 UI 中修改 themeColor│├──→ 组件本地状态更新 → UI 重新渲染│└──→ AppStorage 更新 → 通知所有监听者│├──→ Page A 的 StorageProp 更新 → UI 刷新├──→ Page B 的 StorageProp 更新 → UI 刷新└──→ 任意 StorageLink 更新 → UI 刷新6.2 与其他装饰器的对比装饰器 存储层级 生命周期 可写范围 典型用途State 组件私有 组件销毁 仅本组件 局部表单输入、展开/折叠Prop 父传子 组件销毁 仅子组件读 接收父组件数据Link 父传子 组件销毁 双向同步 父子组件联动Provide/Consume 组件树 组件树销毁 双向同步 跨多层组件通信StorageProp 应用级 进程级 全局写 主题、登录态、全局设置StorageLink 应用级 进程级 全局写 同 StorageProp但双向性更强LocalStorageProp 页面级 页面销毁 仅本页面 页面临时偏好LocalStorageLink 页面级 页面销毁 仅本页面 页面级双向同步6.3 StorageProp 的底层实现原理简化版// 伪代码理解 StorageProp 的工作机制class AppStorageManager {private static store: Mapstring, any new Map();private static watchers: Mapstring, Set new Map();static setOrCreate(key: string, value: any): void { if (!this.store.has(key)) { this.store.set(key, value); } } static set(key: string, value: any): void { this.store.set(key, value); // 通知所有监听该 key 的组件 this.watchers.get(key)?.forEach(callback callback(value)); } static get(key: string): any { return this.store.get(key); }}StorageProp 装饰器在编译期会注入 getter/settersetter 中自动调用 AppStorage.set(key, newValue)从而触发所有监听者的刷新。七、最佳实践与陷阱规避7.1 ✅ 最佳实践统一在 EntryAbility 中初始化onCreate(want, launchParam) {AppStorage.setOrCreate(‘key1’, defaultValue1);AppStorage.setOrCreate(‘key2’, defaultValue2);// … 集中管理所有全局 key}2. 使用常量管理 key 名称// AppStorageKeys.etsexport const AppStorageKeys {THEME_COLOR: ‘themeColor’,FONT_SIZE: ‘fontSize’,IS_DARK_MODE: ‘isDarkMode’,USER_NAME: ‘userName’,} as const;3. 配合 PersistentStorage 实现跨进程持久化// 在 Ability 中PersistentStorage.persistProp(‘themeColor’, ‘#007AFF’);// 应用关闭后重新打开themeColor 保持用户上次设置的值7.2 ⚠️ 常见陷阱陷阱 1在非 Component 文件中访问 AppStorage// ❌ 错误工具类中直接访问class ThemeUtil {static getColor(): string {return AppStorage.get(‘themeColor’); // 可能为 undefined}}// ✅ 正确使用 AppStorage.get 前先确保 key 存在class ThemeUtil {static getColor(): string {return AppStorage.get(‘themeColor’) ?? ‘#007AFF’;}}陷阱 2key 名称拼写不一致// 页面 AStorageProp(‘themeColor’) themeColor: string ‘#007AFF’;// 页面 B — 不小心多写了一个空格StorageProp(themeColor ) themeColor: string ‘#000000’; // ❌ 不同 key陷阱 3忘记默认值声明StorageProp(‘fontSize’) fontSize: number; // ❌ 需要默认值// 运行时可能报 undefined 错误StorageProp(‘fontSize’) fontSize: number 16; // ✅陷阱 4StorageProp 不支持复杂对象某些版本// ⚠️ 某些版本限制只支持 string / number / booleanStorageProp(‘userProfile’) userProfile: UserProfile {}; // 可能不支持// 建议用 JSON 序列化StorageProp(‘userProfileJSON’) userProfileJSON: string ‘{}’;7.3 性能考量按需绑定 不要把所有 AppStorage key 都绑定到每个页面只绑定当前页面需要的避免高频写入 如果每秒需要写入数十次如实时绘图坐标考虑用 State 防抖最后一次性写入 AppStorage合理分层 StorageProp 适合低频变化的全局状态主题、语言、登录态高频 UI 动画状态用 State八、扩展场景8.1 多 Tab 页共享主题// TabPageA.etsStorageProp(‘themeColor’) themeColor: string ‘#007AFF’;// TabPageB.etsStorageProp(‘themeColor’) themeColor: string ‘#007AFF’;// 在 TabPageA 切换颜色 → TabPageB 自动刷新8.2 登录态管理// 登录成功时AppStorage.setOrCreate(‘isLoggedIn’, true);AppStorage.setOrCreate(‘userToken’, ‘xxx-xxx-xxx’);AppStorage.setOrCreate(‘userInfo’, JSON.stringify({ name: ‘张三’, role: ‘admin’ }));// 任何页面StorageProp(‘isLoggedIn’) isLoggedIn: boolean false;// 根据 isLoggedIn 控制 UI 显示8.3 多语言切换// 设置语言AppStorage.setOrCreate(‘locale’, ‘zh-CN’);// 任意页面StorageProp(‘locale’) locale: string ‘zh-CN’;// 配合资源管理实现全局语言切换getText(key: string): string {return i18n.get(key, this.locale);}九、完整代码清单9.1 StoragePropDemo.ets/**StoragePropDemo.etsStorageProp LocalStorage AppStorage 持久化布局演示*/import { promptAction } from ‘kit.ArkUI’;// AppStorage 初始化文件模块级防御性初始化AppStorage.SetOrCreate(‘themeColor’, ‘#007AFF’);AppStorage.SetOrCreate(‘fontSize’, 16);AppStorage.SetOrCreate(‘isDarkMode’, false);AppStorage.SetOrCreate(‘userName’, ‘HarmonyOS 用户’);const COLOR_PRESETS: string[] [‘#007AFF’, ‘#FF3B30’, ‘#34C759’,‘#FF9500’, ‘#AF52DE’, ‘#5AC8FA’,];EntryComponentstruct StoragePropDemo {/* ---- StorageProp与 AppStorage 双向绑定 ---- */StorageProp(‘themeColor’) themeColor: string ‘#007AFF’;StorageProp(‘fontSize’) fontSize: number 16;StorageProp(‘isDarkMode’) isDarkMode: boolean false;StorageProp(‘userName’) userName: string ‘HarmonyOS 用户’;/* ---- LocalStorageProp页面级存储 ---- */LocalStorageProp(‘pageTitle’) pageTitle: string ‘AppStorage 持久化布局演示’;State currentColorIndex: number 0;build() {Scroll() {Column() {// 标题区Text(this.pageTitle).fontSize(22).fontWeight(FontWeight.Bold).fontColor(this.isDarkMode ? ‘#FFFFFF’ : ‘#1A1A1A’).margin({ top: 24, bottom: 8 }).width(‘100%’).textAlign(TextAlign.Center)Text(StorageProp LocalStorage AppStorage) .fontSize(13).fontColor(#888888).margin({ bottom: 20 }) .width(100%).textAlign(TextAlign.Center) // 状态总览 Card({ title: 当前状态总览, bgColor: this.isDarkMode ? #2C2C2C : #F5F5F7 }) { this.buildStatusOverview() } // 主题色选择器 Card({ title: 主题色AppStorage 持久化, bgColor: this.isDarkMode ? #2C2C2C : #F5F5F7 }) { this.buildColorPicker() } // 字体大小 Card({ title: 字体大小AppStorage 持久化, bgColor: this.isDarkMode ? #2C2C2C : #F5F5F7 }) { this.buildFontSizeSlider() } // 暗黑模式 Card({ title: 暗黑模式AppStorage 持久化, bgColor: this.isDarkMode ? #2C2C2C : #F5F5F7 }) { this.buildDarkModeToggle() } // 用户名 Card({ title: 用户名AppStorage 持久化, bgColor: this.isDarkMode ? #2C2C2C : #F5F5F7 }) { this.buildUserNameEditor() } // 实时预览 Card({ title: ✨ 实时效果预览, bgColor: this.isDarkMode ? #2C2C2C : #F5F5F7 }) { this.buildPreviewPane() } Text( 提示页面内的所有设置都通过 StorageProp 绑定到 AppStorage。\n返回后重新进入或跳转其他页面这些设置仍然保持。) .fontSize(12).fontColor(#999999).margin({ top: 16, bottom: 32 }) .lineHeight(20).padding({ left: 16, right: 16 }).width(100%) }.width(100%).padding({ left: 16, right: 16, bottom: 32 }) }.width(100%).height(100%) .backgroundColor(this.isDarkMode ? #1A1A1A : #FFFFFF)}BuilderbuildStatusOverview() {Column({ space: 8 }) {this.buildInfoRow(‘主题色’, this.themeColor)this.buildInfoRow(‘字体大小’, this.fontSize ‘fp’)this.buildInfoRow(‘暗黑模式’, this.isDarkMode ? ‘已开启’ : ‘已关闭’)this.buildInfoRow(‘用户名’, this.userName)}.padding({ top: 8, bottom: 8 })}BuilderbuildInfoRow(label: string, value: string) {Row() {Text(label ‘’).fontSize(14).fontColor(this.isDarkMode ? ‘#CCCCCC’ : ‘#666666’)Text(value).fontSize(14).fontColor(this.themeColor).fontWeight(FontWeight.Medium)}.width(‘100%’).justifyContent(FlexAlign.SpaceBetween)}BuilderbuildColorPicker() {Column({ space: 12 }) {Text(‘当前选中色’ this.themeColor).fontSize(14).fontColor(this.isDarkMode ? ‘#CCCCCC’ : ‘#333333’)Flex({ wrap: FlexWrap.Wrap, justifyContent: FlexAlign.Center }) {ForEach(COLOR_PRESETS, (color: string) {Column() {Circle().width(40).height(40).fill(color).margin(6).onClick(() {this.themeColor color;promptAction.showToast({ message: ‘主题色已切换为 ’ color });})if (this.themeColor color) {Circle().width(8).height(8).fill(’#FFFFFF’).stroke(this.themeColor).strokeWidth(2)}}.padding({ left: 4, right: 4 })})}.width(‘100%’).padding({ top: 8, bottom: 8 })}}BuilderbuildFontSizeSlider() {Column({ space: 8 }) {Row() {Text(‘A’).fontSize(12).fontColor(this.isDarkMode ? ‘#CCCCCC’ : ‘#666666’)Slider({ value: this.fontSize, min: 12, max: 24, step: 1,style: SliderStyle.OutSet }).blockColor(this.themeColor).trackColor(this.isDarkMode ? ‘#444444’ : ‘#E0E0E0’).selectedColor(this.themeColor).onChange((value: number) { this.fontSize value; }).layoutWeight(1)Text(‘A’).fontSize(24).fontColor(this.isDarkMode ? ‘#CCCCCC’ : ‘#666666’)}.width(‘100%’)Text(‘当前字号’ this.fontSize ‘fp’).fontSize(13).fontColor(this.isDarkMode ? ‘#AAAAAA’ : ‘#888888’).textAlign(TextAlign.Center).width(‘100%’)}.padding({ top: 4, bottom: 4 })}BuilderbuildDarkModeToggle() {Row() {Text(this.isDarkMode ? ‘ 暗黑模式已开启’ : ‘☀️ 亮色模式’).fontSize(16).fontColor(this.isDarkMode ? ‘#FFFFFF’ : ‘#333333’).layoutWeight(1)Toggle({ type: ToggleType.Switch, isOn: this.isDarkMode }).selectedColor(this.themeColor).switchPointColor(‘#FFFFFF’).onChange((isOn: boolean) {this.isDarkMode isOn;promptAction.showToast({message: isOn ? ‘已切换到暗黑模式’ : ‘已切换到亮色模式’});})}.width(‘100%’).padding({ top: 8, bottom: 8 })}BuilderbuildUserNameEditor() {Column({ space: 8 }) {TextInput({ placeholder: ‘请输入用户名’, text: this.userName }).fontSize(16).fontColor(this.isDarkMode ? ‘#FFFFFF’ : ‘#333333’).backgroundColor(this.isDarkMode ? ‘#3C3C3C’ : ‘#FFFFFF’).placeholderColor(this.isDarkMode ? ‘#888888’ : ‘#CCCCCC’).borderRadius(8).border({ width: 1, color: this.isDarkMode ? ‘#555555’ : ‘#E0E0E0’ }).onChange((value: string) { this.userName value; }).height(44)Text(‘按回车或点击空白处确认修改’).fontSize(12).fontColor(‘#999999’)}.padding({ top: 4, bottom: 4 })}BuilderbuildPreviewPane() {Column({ space: 12 }) {Column({ space: 8 }) {Text(‘Hello, ’ this.userName ‘!’).fontSize(this.fontSize).fontColor(this.themeColor).fontWeight(FontWeight.Bold).textAlign(TextAlign.Center).width(‘100%’)Text(‘当前主题色’ this.themeColor ’ · 字号’ this.fontSize ‘fp’).fontSize(13).fontColor(this.isDarkMode ? ‘#AAAAAA’ : ‘#666666’).textAlign(TextAlign.Center).width(‘100%’)}.padding(16).backgroundColor(this.isDarkMode ? ‘#333333’ : ‘#F0F8FF’).borderRadius(12).border({ width: 2, color: this.themeColor }).width(‘100%’)Text(【底层原理】).fontSize(14).fontWeight(FontWeight.Bold) .fontColor(this.isDarkMode ? #CCCCCC : #333333).margin({ top: 4 }) Text(StorageProp(\themeColor\) 将 themeColor 绑定到 AppStorage。\n 每次修改 themeColorAppStorage自动更新所有监听该key的页面同步刷新。\n\n AppStorage 生命周期 应用进程生命周期。即使用户切换到其他页面再返回所有状态保持不变。) .fontSize(12).fontColor(this.isDarkMode ? #999999 : #666666).lineHeight(20) }.padding({ top: 8, bottom: 8 })}}Componentstruct Card {Prop title: string ‘’;BuilderParam content: () void this.emptyContent;Prop bgColor: string ‘#F5F5F7’;Builder emptyContent() {}build() {Column() {Text(this.title).fontSize(16).fontWeight(FontWeight.Bold).fontColor(‘#1A1A1A’).margin({ bottom: 12 }).width(‘100%’)this.content()}.width(‘100%’).padding(16).backgroundColor(this.bgColor).borderRadius(12).margin({ bottom: 12 })}}9.2 EntryAbility.ets 中的初始化onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {// …AppStorage.SetOrCreate(‘themeColor’, ‘#007AFF’);AppStorage.SetOrCreate(‘fontSize’, 16);AppStorage.SetOrCreate(‘isDarkMode’, false);AppStorage.SetOrCreate(‘userName’, ‘HarmonyOS 用户’);}十、运行效果预览启动应用后从首页点击导航按钮进入演示页可以看到状态总览卡片 — 实时显示所有 AppStorage 中的当前值主题色选择器 — 6 色环点击切换主题色即刻生效并持久化字体大小滑块 — 12~24fp 可调拖动即生效暗黑模式开关 — 一键切换暗黑/亮色整个页面 UI 自适应用户名输入 — 实时同步到 AppStorage实时预览卡片 — 集成展示所有设置的综合效果切换到其他页面再返回所有设置 保持不变 — 这就是 AppStorage 持久化的威力。十一、总结StorageProp LocalStorage AppStorage 构成了鸿蒙 ArkTS 中 应用级状态管理 的完整方案AppStorage 提供全局数据总线跨越页面边界StorageProp 将组件属性与 AppStorage 响应式绑定实现零模板代码的状态同步LocalStorage 补充页面级存储避免滥用全局 key三者的组合适用于✅ 主题/换肤系统✅ 多语言切换✅ 用户登录态管理✅ 全局设置面板✅ 任何需要跨页面共享状态的场景下一篇文章将深入探讨如何将 PersistentStorage 与 AppStorage 配合实现 应用重启后仍保持 的真正持久化方案。本文对应的完整源代码位于 Demo0626/ 项目目录可直接在 DevEco Studio 中打开并运行。