鸿蒙应用开发-应用状态存储(LocalStorage、AppStorage..)

1. UIAbility内状态-LocalStorage

LocalStorage 是页面级的UI状态存储,通过 @Entry 装饰器接收的参数可以在页面内共享同一个 LocalStorage 实例。 LocalStorage 也可以在 UIAbility 内,页面间共享状态。

1)页面内共享

  • 创建 LocalStorage 实例:const storage = new LocalStorage({ key: value })
  • 单向 @LocalStorageProp('user') 组件内可变
  • 双向 @LocalStorageLink('user') 全局均可变
ts 复制代码
class User {
  name?: string
  age?: number
}
const storage = new LocalStorage({
  user: { name: 'jack', age: 18 }
})

@Entry(storage)
@Component
struct Index {
  @LocalStorageProp('user')
  user: User = {}

  build() {
    Column({ space: 15 }){
      Text('Index:')
      Text(this.user.name + this.user.age)
      Divider()
      ChildA()
      Divider()
      ChildB()
    }
    .width('100%')
    .height('100%')
    .justifyContent(FlexAlign.Center)
  }
}

@Component
struct ChildA {
  @LocalStorageProp('user')
  user: User = {}

  build() {
    Column({ space: 15 }){
      Text('ChildA:')
      Text(this.user.name + this.user.age)
        .onClick(()=>{
          this.user.age ++
        })
    }
  }
}

@Component
struct ChildB {
  @LocalStorageLink('user')
  user: User = {}

  build() {
    Column({ space: 15 }){
      Text('ChildB:')
      Text(this.user.name + this.user.age)
        .onClick(()=>{
          this.user.age ++
        })
    }
  }
}

2)页面间共享

  • UIAbility 创建 LocalStorage 通过 loadContent 提供给加载的窗口

在页面使用 const storage = LocalStorage.GetShared() 得到实例,通过 @Entry(storage) 传入页面

entryAbility/EntryAbility.ts

ts 复制代码
+  storage = new LocalStorage({
+    user: { name: 'jack', age: 18 }
+  })

  onWindowStageCreate(windowStage: window.WindowStage) {
    // Main window is created, set main page for this ability
    hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate');

+    windowStage.loadContent('pages/Index', this.storage , (err, data) => {
      if (err.code) {
        hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? '');
        return;
      }
      hilog.info(0x0000, 'testTag', 'Succeeded in loading the content. Data: %{public}s', JSON.stringify(data) ?? '');
    });
  }

models/index.ets

ts 复制代码
export class User {
  name?: string
  age?: number
}

pages/Index.ets

ts 复制代码
import { User } from '../models'
const storage = LocalStorage.GetShared()

@Entry(storage)
@Component
struct Index {
  @LocalStorageProp('user')
  user: User = {}

  build() {
    Column({ space: 15 }) {
      Text('Index:')
      Text(this.user.name + this.user.age)
        .onClick(()=>{
          this.user.age ++
        })
      Navigator({ target: 'pages/OtherPage' }){
        Text('Go Other Page')
      }
    }
    .width('100%')
    .height('100%')
    .justifyContent(FlexAlign.Center)
  }
}

pages/OtherPage.ets

ts 复制代码
import { User } from '../models'
const storage = LocalStorage.GetShared()

@Entry(storage)
@Component
struct OtherPage {
  @LocalStorageLink('user')
  user: User = {}

  build() {
    Column({ space: 15 }) {
      Text('OtherPage:')
      Text(this.user.name + this.user.age)
        .onClick(()=>{
          this.user.age ++
        })
    }
    .width('100%')
    .height('100%')
    .justifyContent(FlexAlign.Center)
  }
}

注意

  • 页面间共享需要要模拟器测试
  • 应用逻辑中使用参考 链接

2. 应用状态-AppStorage

AppStorage 是应用全局的UI状态存储,是和应用的进程绑定的,由UI框架在应用程序启动时创建,为应用程序UI状态属性提供中央存储。

如果是初始化使用 AppStorage.SetOrCreate(key,value)

单向 @StorageProp('user') 组件内可变

双向 @StorageLink('user') 全局均可变

1)通过UI装饰器使用

ts 复制代码
import { User } from '../models'

AppStorage.SetOrCreate<User>('user', { name: 'jack', age: 18 })

@Entry
@Component
struct Index {
  @StorageProp('user')
  // 可忽略,编辑器类型错误
  user: User = {}

  build() {
    Column({ space: 15 }) {
      Text('Index:')
      Text(this.user.name + this.user.age)
        .onClick(() => {
          this.user.age++
        })
      Divider()
      ChildA()
    }
    .width('100%')
    .height('100%')
    .justifyContent(FlexAlign.Center)
  }
}

@Component
struct ChildA {
  @StorageLink('user')
  user: User = {}

  build() {
    Column({ space: 15 }){
      Text('ChildA:')
      Text(this.user.name + this.user.age)
        .onClick(()=>{
          this.user.age ++
        })
    }
  }
}

2)通过逻辑使用

  • AppStorage.Get<ValueType>(key) 获取数据
  • AppStorage.Set<ValueType>(key,value) 覆盖数据
  • const link: SubscribedAbstractProperty<ValueType> = AppStorage.Link(key)覆盖数据
    • link.set(value) 修改
    • link.get() 获取
ts 复制代码
import promptAction from '@ohos.promptAction'
import { User } from '../models'

AppStorage.SetOrCreate<User>('user', { name: 'jack', age: 18 })

@Entry
@Component
struct Index {
  @StorageLink('user')
  user: User = {}

  build() {
    Column({ space: 15 }) {
      Text('Index:')
      Text(this.user.name + this.user.age)
        .onClick(() => {
          this.user.age++
        })
      Divider()
      Text('Get()')
        .onClick(() => {
          // 仅获取
          const user = AppStorage.Get<User>('user')
          promptAction.showToast({
            message: JSON.stringify(user)
          })
        })
      Text('Set()')
        .onClick(() => {
          // 直接设置
          AppStorage.Set<User>('user', {
            name: 'tom',
            age: 100
          })
          // 观察页面更新没
        })
      Text('Link()')
        .onClick(() => {
          // 获取user的prop
          const user: SubscribedAbstractProperty<User> = AppStorage.Link('user')
          user.set({
            name: user.get().name,
            // 获取后修改
            age: user.get().age + 1
          })
        })
    }
    .width('100%')
    .height('100%')
    .justifyContent(FlexAlign.Center)
  }
}

3. 状态持久化-PersistentStorage

PersistentStorage 将选定的 AppStorage 属性保留在设备磁盘上。

DETAILS

UI和业务逻辑不直接访问 PersistentStorage 中的属性,所有属性访问都是对 AppStorage 的访问,AppStorage 中的更改会自动同步到 PersistentStorage

WARNING

  • 支持:number, string, boolean, enum 等简单类型;
  • 如果:要支持对象类型,可以转换成json字符串
  • 持久化变量最好是小于2kb的数据,如果开发者需要存储大量的数据,建议使用数据库api。

1)简单数据类型的持久化,和获取和修改

ts 复制代码
import { User } from '../models'

PersistentStorage.PersistProp('count', 100)

@Entry
@Component
struct Index {
  @StorageLink('count')
  count: number = 0

  build() {
    Column({ space: 15 }) {
      Text(this.count.toString())
        .onClick(() => {
          this.count++
        })
    }
    .width('100%')
    .height('100%')
    .justifyContent(FlexAlign.Center)
  }
}

2)复杂数据类型的持久化,和获取和修改

ts 复制代码
import promptAction from '@ohos.promptAction'
import { User } from '../models'

PersistentStorage.PersistProp('userJson', `{ "name": "jack", "age": 18 }`)

@Entry
@Component
struct Index {
  @StorageProp('userJson')
  @Watch('onUpdateUser')
  userJson: string = '{}'
  @State
  user: User = JSON.parse(this.userJson)

  onUpdateUser() {
    this.user = JSON.parse(this.userJson)
  }

  build() {
    Column({ space: 15 }) {
      Text('Index:')
      Text(this.user.name + this.user.age)
        .onClick(() => {
          this.user.age++
          // 修改
          AppStorage.Set('userJson', JSON.stringify(this.user))
        })
      Divider()
      Text('Get()')
        .onClick(() => {
          // 获取
          const user = AppStorage.Get<string>('userJson')
          promptAction.showToast({ message: user })
        })
    }
    .width('100%')
    .height('100%')
    .justifyContent(FlexAlign.Center)
  }
}

4. 设备环境-Environment

开发者如果需要应用程序运行的设备的环境参数,以此来作出不同的场景判断,比如多语言,暗黑模式等,需要用到Environment 设备环境查询。
Environment 的所有属性都是不可变的(即应用不可写入),所有的属性都是简单类型。
👀关注公众号:Android老皮!!!欢迎大家来找我探讨交流👀

相关推荐
lqj_本人2 小时前
鸿蒙next版开发:分析JS Crash(进程崩溃)
华为·harmonyos
Harmony_QI2 小时前
鸿蒙北向开发环境安装指南
华为·harmonyos·鸿蒙
lqj_本人11 小时前
鸿蒙next版开发:相机开发-适配不同折叠状态的摄像头变更(ArkTS)
数码相机·华为·harmonyos
呆萌很19 小时前
HCIP-HarmonyOS Application Developer 习题(二十二)
harmonyos
郝晨妤19 小时前
[HarmonyOS]简单说一下鸿蒙架构
华为·架构·harmonyos·鸿蒙
二流小码农1 天前
鸿蒙开发:ForEach中为什么键值生成函数很重要
android·ios·harmonyos
Kousi1 天前
AlphabetIndexer组件,鸿蒙开发
前端·javascript·harmonyos
我爱鸿蒙开发1 天前
ArkTS的进阶语法(函数补充与正则表达式)
前端·harmonyos
爱健身的程序员1 天前
鸿蒙应用开发--状态管理
前端·harmonyos