HarmonyOS鸿蒙Next中使用AppStorage实现跨页面数据共享

HarmonyOS鸿蒙Next中使用AppStorage实现跨页面数据共享 如何使用AppStorage实现跨页面数据共享?

3 回复

问题

我有两个不相关的页面,比如“个人资料页”和“设置页”。它们都需要显示用户名。如果用户在“设置页”修改了用户名,我希望“个人资料页”在下次显示时能自动更新。我不想通过路由参数层层传递,因为这两个页面可能没有直接的导航关系。

核心概念解析

AppStorage是整个应用进程共享的单例KeyValue存储系统。它在应用启动时创建,在应用退出时销毁。存放在AppStorage中的数据是“响应式”的,这意味着当数据变化时,依赖这些数据的UI组件会自动重新渲染。

实现效果

cke_2515.png

cke_2913.png

cke_4711.png

完整示例代码

import router from '@ohos.router';

// 初始化一个全局的 'userName' 状态
AppStorage.setOrCreate('userName', '鸿蒙开发者');


@Entry
@Component
struct ProfilePage {
  // 1. 使用 @StorageLink 与 AppStorage 中的 'userName' 建立双向绑定
  @StorageLink('userName') userName: string = '';

  build() {
    Column() {
      Text('个人资料')
        .fontSize(24)
        .fontWeight(FontWeight.Bold)
        .margin({ top: 50, bottom: 30 })

      // 用户信息卡片
      Column({ space: 15 }) {
        Image($r('app.media.background')) // 假设有一个头像图标
          .width(80)
          .height(80)
          .borderRadius(40)

        Text(`用户名: ${this.userName}`)
          .fontSize(20)
          .fontWeight(FontWeight.Medium)
      }
      .width('90%')
      .padding(20)
      .backgroundColor('#FFFFFF')
      .borderRadius(12)
      .shadow({ radius: 8, color: '#1A000000', offsetX: 0, offsetY: 2 })

      Blank()

      Button('前往设置页修改')
        .width('80%')
        .margin({ bottom: 20 })
        .onClick(() => {
          router.pushUrl({ url: '/pages/1221/SettingsPage' });
        })
    }
    .width('100%')
    .height('100%')
    .backgroundColor('#F1F3F5')
    .justifyContent(FlexAlign.Start)
    .alignItems(HorizontalAlign.Center)
  }
}



==========================================

import router from '@ohos.router';

@Entry
@Component
struct SettingsPage {
  // 同样使用 @StorageLink 绑定,这样如果在此页面修改,ProfilePage也能感知到
  @StorageLink('userName') currentUserName: string = '';
  // 本地状态,用于输入框的临时值
  @State inputText: string = '';

  aboutToAppear() {
    // 页面出现时,用全局状态初始化输入框的值
    this.inputText = this.currentUserName;
  }

  build() {
    Column() {
      Text('设置')
        .fontSize(24)
        .fontWeight(FontWeight.Bold)
        .margin({ top: 50, bottom: 30 })

      // 用户名设置项
      Row() {
        Text('用户名')
          .fontSize(18)
          .layoutWeight(1)

        TextInput({ placeholder: '请输入新用户名' })
          .width('60%')
          .fontSize(16)
          .onChange((value: string) => {
            this.inputText = value;
          })
      }
      .width('90%')
      .padding(16)
      .backgroundColor('#FFFFFF')
      .justifyContent(FlexAlign.SpaceBetween)
      .borderRadius(8)

      Blank()

      Button('保存修改')
        .width('80%')
        .margin({ bottom: 20 })
        .onClick(() => {
          // 2. 点击保存时,更新 AppStorage 中的值
          AppStorage.setOrCreate('userName', this.inputText);
          console.info(`用户名已更新为: ${this.inputText}`);
          // 提示用户并返回
          // 可以使用 promptAction.showToast({ message: '保存成功' }) 等方式提示
          router.back();
        })
    }
    .width('100%')
    .height('100%')
    .backgroundColor('#F1F3F5')
    .justifyContent(FlexAlign.Start)
    .alignItems(HorizontalAlign.Center)
  }
}

更多关于HarmonyOS鸿蒙Next中使用AppStorage实现跨页面数据共享的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


在HarmonyOS Next中,AppStorage是应用全局的键值对存储,支持跨页面数据共享。通过@StorageLink@StorageProp装饰器,组件可绑定AppStorage中的数据,实现自动同步更新。@StorageLink建立双向绑定,组件修改会同步到AppStorage;@StorageProp建立单向绑定,仅响应AppStorage的更新。

在HarmonyOS Next中,AppStorage 是应用全局的UI状态存储,非常适合用于实现跨页面、跨组件的全局数据共享。它相当于一个响应式的“全局单例”,当数据变更时,依赖该数据的UI会自动更新。

核心使用方法如下:

  1. 链接组件状态到AppStorage:使用 @StorageLink@StorageProp 装饰器。

    • @StorageLink(key):组件与AppStorage建立双向同步。组件内修改会同步到AppStorage,并触发其他依赖该key的UI更新。
    • @StorageProp(key):组件与AppStorage建立单向同步。AppStorage的变更会同步到组件,但组件内的修改不会更新回AppStorage。
  2. 在UI组件中使用

    // 在组件中声明一个与AppStorage中'keyName'双向绑定的变量
    @StorageLink('keyName') myData: string = 'default';
    // 或单向绑定
    @StorageProp('keyName') myReadOnlyData: string = 'default';
    
  3. 在非UI组件(逻辑层)中访问和操作:直接使用 AppStorage 的API。

    // 设置/更新数据
    AppStorage.SetOrCreate('keyName', 'newValue');
    // 获取数据
    let value = AppStorage.Get('keyName');
    // 删除数据
    AppStorage.Delete('keyName');
    // 判断是否存在
    let hasKey = AppStorage.Has('keyName');
    

一个简单的跨页面共享示例:

假设需要在页面A设置一个用户名,并在页面B显示。

  • 页面A (设置数据):
    import { AppStorage } from '@ohos.application.Storage';
    
    @Entry
    @Component
    struct PageA {
      // 本地状态,通过按钮或其他交互更新
      private inputName: string = '';
    
      build() {
        Column() {
          TextInput({ placeholder: '输入用户名' })
            .onChange((value: string) => {
              this.inputName = value;
            })
          Button('保存到全局')
            .onClick(() => {
              // 将数据保存到AppStorage
              AppStorage.SetOrCreate('userName', this.inputName);
            })
        }
      }
    }
    
  • 页面B (读取并响应数据):
    @Entry
    @Component
    struct PageB {
      // 与AppStorage中的'userName'建立双向绑定
      @StorageLink('userName') currentUser: string = '';
    
      build() {
        Column() {
          // 这里会显示AppStorage中'userName'的值,并随其更新而自动更新
          Text(`当前用户: ${this.currentUser}`)
            .fontSize(30)
        }
      }
    }
    

关键注意事项:

  • AppStorage 的key是全局唯一的字符串。
  • @StorageLink@StorageProp 装饰的变量必须在组件内部初始化,但初始值会被AppStorage中对应key的值覆盖(如果存在)。
  • 对于复杂对象,AppStorage会进行深度观察(deep watch),但其变更检测基于引用。直接修改对象内部属性(如 this.someObj.property = newValue不会触发UI更新。正确做法是创建一个新对象并重新赋值给该变量。
  • LocalStorage (页面内UI状态共享)不同,AppStorage 是应用级别的,生命周期与应用一致。

通过上述方式,你可以轻松地在HarmonyOS Next应用的不同页面或组件间共享和管理全局响应式数据。

回到顶部