MiniX自绘渲染跨平台框架
  • 框架说明
  • 声明式开发范式
  • 内置Api
指南
接口
  • Minix CLI
示例
  • 类Web框架

    • 框架说明
    • 类Web开发范式
    • 内置Api
  • 指南
  • 组件
  • 接口
  • 示例
  • 规范
  • DophinHybrid

    • 快速上手 (opens new window)
    • UI 组件库 (opens new window)
    • jsBridge 接口 (opens new window)
  • DolphinWeex

    • 快速上手 (opens new window)
    • UI 组件库 (opens new window)
    • jsBridge 接口 (opens new window)
  • 发布消息
  • 常见问题
  • 更新日志
  • 框架说明
  • 声明式开发范式
  • 内置Api
指南
接口
  • Minix CLI
示例
  • 类Web框架

    • 框架说明
    • 类Web开发范式
    • 内置Api
  • 指南
  • 组件
  • 接口
  • 示例
  • 规范
  • DophinHybrid

    • 快速上手 (opens new window)
    • UI 组件库 (opens new window)
    • jsBridge 接口 (opens new window)
  • DolphinWeex

    • 快速上手 (opens new window)
    • UI 组件库 (opens new window)
    • jsBridge 接口 (opens new window)
  • 发布消息
  • 常见问题
  • 更新日志
  • 框架说明

    • 概述
    • 声明式 UI 语法

      • 基本 UI 描述
      • 状态管理

        • 基本概念
        • 页面级变量的状态管理
        • 应用级变量的状态管理
          • AppStorage
          • LocalStorage
          • PersistentStorage
          • Environment
      • 动态构建 UI 元素
      • 渲染控制
      • 使用限制与扩展
    • 深入理解组件化

    • 应用生命周期
    • 资源管理

    • 像素单位
    • 应用包结构配置文件的说明
  • 常见布局开发指导

  • 性能提升的推荐方法

# 应用级变量的状态管理

在前面的章节中,已经讲述了如何管理页面级变量的状态,本章将说明如何管理应用级变量的状态,具体接口说明请参考应用级变量的状态管理接口。

# AppStorage

AppStorage是应用程序中的单例对象,由 UI 框架在应用程序启动时创建,在应用程序退出时销毁,为应用程序范围内的可变状态属性提供中央存储。

AppStorage 包含整个应用程序中需要访问的所有状态属性,只要应用程序保持运行,AppStorage 就会保存所有属性及属性值,属性值可以通过唯一的键值进行访问。

组件可以通过装饰器将应用程序状态数据与 AppStorage 进行同步,应用业务逻辑的实现也可以通过接口访问 AppStorage。

AppStorage 的选择状态属性可以与不同的数据源或数据接收器同步,这些数据源和接收器可以是设备上的本地或远程,并具有不同的功能,如数据持久性。这样的数据源和接收器可以独立于 UI 在业务逻辑中实现。

默认情况下,AppStorage 中的属性是可变的,AppStorage 还可使用不可变(只读)属性。

说明:Worker和主线程只能通过postMessage交互,不能使用 AppStorage 进行交互。

# @StorageLink 装饰器

组件通过使用@StorageLink(key)装饰的状态变量,与 AppStorage 建立双向数据绑定,key 为 AppStorage 中的属性键值。当创建包含@StorageLink 的状态变量的组件时,该状态变量的值将使用 AppStorage 中的值进行初始化。在 UI 组件中对@StorageLink 的状态变量所做的更改将同步到 AppStorage,并从 AppStorage 同步到任何其他绑定实例中,如 PersistentStorage 或其他绑定的 UI 组件。

# @StorageProp 装饰器

组件通过使用@StorageProp(key)装饰的状态变量,与 AppStorage 建立单向数据绑定,key 标识 AppStorage 中的属性键值。当创建包含@StorageProp 的状态变量的组件时,该状态变量的值将使用 AppStorage 中的值进行初始化。AppStorage 中属性值的更改会导致绑定该状态变量的 UI 组件进行状态更新。

# 示例

每次用户单击 Count 按钮时,this.varA 变量值都会增加 1,此变量与 AppStorage 中的 varA 同步。每次用户单击 language 按钮时,修改 AppStorage 中的 languageCode,此修改会同步给 this.languageCode 变量。

// xxx.ets
@Entry
@Component
struct ComponentA {
  @StorageLink('varA') varA: number = 2
  @StorageProp('languageCode') languageCode: string = 'en'
  private label: string = 'count'

  aboutToAppear() {
    this.label = (this.languageCode === 'zh') ? '数量' : 'Count'
  }

  build() {
    Column() {
      Row({ space: 20 }) {
        Button(`${this.label}: ${this.varA}`)
          .onClick(() => {
            AppStorage.Set<number>('varA', AppStorage.Get<number>('varA') + 1)
          })
        Button(`language: ${this.languageCode}`)
          .onClick(() => {
            if (AppStorage.Get<string>('languageCode') === 'zh') {
              AppStorage.Set<string>('languageCode', 'en')
            } else {
              AppStorage.Set<string>('languageCode', 'zh')
            }
            this.label = (this.languageCode === 'zh') ? '数量' : 'Count'
          })
      }
      .margin({ bottom: 50 })

      Row() {
        Button(`更改@StorageLink修饰的变量:${this.varA}`).height(40).fontSize(14)
          .onClick(() => {
            this.varA++
          })
      }.margin({ bottom: 50 })

      Row() {
        Button(`更改@StorageProp修饰的变量:${this.languageCode}`).height(40).fontSize(14)
          .onClick(() => {
            if (this.languageCode === 'zh') {
              this.languageCode = 'en'
            } else {
              this.languageCode = 'zh'
            }
          })
      }
    }
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51

appstorage

# LocalStorage

说明:

该接口从 API version 9 开始支持。后续版本如有新增内容,则采用上角标单独标记该内容的起始版本。

LocalStorage是应用程序中的存储单元,生命周期跟随其关联的 Ability。LocalStorage 为应用程序范围内的可变状态属性和非可变状态属性提供存储,可变状态属性和非可变状态属性是构建应用程序 UI 的一部分,如一个 Ability 的 UI。

应用层:一个应用程序可以创建多个 LocalStorage 实例,应用程序的每一个 Ability 对应一个 LocalStorage 实例。

Ability:一个应用程序可以拥有多个 Ability,一个 Ability 中的所有子组件最多可以分配一个 LocalStorage 实例。并且,Ability 中的所有子组件都将继承对此 LocalStorage 实例存储对象的访问权。

一个组件最多可以访问一个 LocalStorage 实例,一个 LocalStorage 对象可以分配给多个组件。

# @LocalStorageLink 装饰器

组件通过使用@LocalStorageLink(key)装饰的状态变量,key 值为 LocalStorage 中的属性键值,与 LocalStorage 建立双向数据绑定。当创建包含@LocalStorageLink 的状态变量的组件时,该状态变量的值将会使用 LocalStorage 中的值进行初始化。如果 LocalStorage 中未定义初始值,将使用@LocalStorageLink 定义的初始值。在 UI 组件中对@LocalStorageLink 的状态变量所做的更改将同步到 LocalStorage 中,并从 LocalStorage 同步到 Ability 下的组件中。

# @LocalStorageProp 装饰器

组件通过使用 LocalStorageProp(key)装饰的状态变量,key 值为 LocalStorage 中的属性键值,与 LocalStorage 建立单向数据绑定。当创建包含@LocalStorageProp 的状态变量的组件时,该状态变量的值将使用 LocalStorage 中的值进行初始化。LocalStorage 中的属性值的更改会导致当前 Ability 下的所有 UI 组件进行状态更新。

说明: 创建 LocalStorage 实例时如未定义初始值,可以使用组件内@LocalStorageLink 和@LocalStorageProp 的初始值。如果定义时给定了初始值,那么不会再使用@LocalStorageLink 和@LocalStorageProp 的初始值。

# 示例 1(在一个 Ability 中创建 LocalStorage)

LocalStorage 通过 loadContent 接口加载,接口说明详见loadContent。

// MainAbility.ts
import Ability from "@ohos.application.Ability";

export default class MainAbility extends Ability {
  storage: LocalStorage;

  onCreate() {
    this.storage = new LocalStorage();
    this.storage.setOrCreate("storageSimpleProp", 121);
    console.info("[Demo MainAbility onCreate]");
  }

  onDestroy() {
    console.info("[Demo MainAbility onDestroy]");
  }

  onWindowStageCreate(windowStage) {
    // storage作为参数传递给loadContent接口
    windowStage.loadContent("pages/index", this.storage);
  }

  onWindowStageDestroy() {
    console.info("[Demo] MainAbility onWindowStageDestroy");
  }

  onForeground() {
    console.info("[Demo] MainAbility onForeground");
  }

  onBackground() {
    console.info("[Demo] MainAbility onBackground");
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

@Component 组件获取数据

// index.ets
let storage = LocalStorage.GetShared()

@Entry(storage)
@Component
struct LocalStorageComponent {
  @LocalStorageLink('storageSimpleProp') simpleVarName: number = 0

  build() {
    Column() {
      Button(`LocalStorageLink: ${this.simpleVarName.toString()}`)
        .margin(20)
        .onClick(() => {
          this.simpleVarName += 1
        })
      Text(JSON.stringify(this.simpleVarName))
        .fontSize(50)
      LocalStorageComponentProp()
    }.width('100%')
  }
}

@Component
struct LocalStorageComponentProp {
  @LocalStorageProp('storageSimpleProp') simpleVarName: number = 0

  build() {
    Column() {
      Button(`LocalStorageProp: ${this.simpleVarName.toString()}`)
        .margin(20)
        .onClick(() => {
          this.simpleVarName += 1
        })
      Text(JSON.stringify(this.simpleVarName))
        .fontSize(50)
    }.width('100%')
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38

appstorage1

# 示例 2(在 Entry 页面定义 LocalStorage)

// xxx.ets
let storage = new LocalStorage({ "PropA": 47 })

@Entry(storage)
@Component
struct ComA {
  @LocalStorageLink("PropA") storageLink: number = 1

  build() {
    Column() {
      Text(`Parent from LocalStorage ${this.storageLink}`)
        .fontSize(18)
        .margin(20)
        .onClick(() => this.storageLink += 1)
      Child()
    }
  }
}

@Component
struct Child {
  @LocalStorageLink("PropA") storageLink: number = 1

  build() {
    Text(`Child from LocalStorage ${this.storageLink}`)
      .fontSize(18)
      .margin(20)
      .onClick(() => this.storageLink += 1)
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

appstorage2

# PersistentStorage

PersistentStorage提供了一些静态方法用来管理应用持久化数据,可以将特定标记的持久化数据链接到 AppStorage 中,并由 AppStorage 接口访问对应持久化数据,或者通过@StorageLink 装饰器来访问对应 key 的变量。

说明:

  • PersistentStorage 的 PersistProp 接口使用时,需要保证输入对应的 key 在 AppStorage 中存在。
  • PersistentStorage 的 DeleteProp 接口使用时,只能对本次应用启动时已经 link 过的数据生效。
// xxx.ets
PersistentStorage.PersistProp('highScore', '0')

@Entry
@Component
struct PersistentComponent {
  @StorageLink('highScore') highScore: string = '0'
  @State currentScore: number = 0

  build() {
    Column() {
      if (this.currentScore === Number(this.highScore)) {
        Text(`new highScore : ${this.highScore}`).fontSize(18)
      }
      Button(`goal!, currentScore : ${this.currentScore}`)
        .margin(20)
        .onClick(() => {
          this.currentScore++
          if (this.currentScore > Number(this.highScore)) {
            this.highScore = this.currentScore.toString()
          }
        })
    }.width('100%')
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

appstorage3

# Environment

Environment是框架在应用程序启动时创建的单例对象,它为 AppStorage 提供了一系列应用程序需要的环境状态数据,这些数据描述了应用程序运行的设备环境,包括系统语言、深浅色模式等等。Environment 及其属性是不可变的,所有数据类型均为简单类型。如下示例展示了从 Environment 获取系统是否开启无障碍屏幕朗读:

Environment.EnvProp("accessibilityEnabled", "default");
var enable = AppStorage.Get("accessibilityEnabled");
1
2

accessibilityEnabled 是 Environment 提供的系统默认变量识别符。首先需要将对应系统属性绑定到 AppStorage 上,再通过 AppStorage 中的方法或者装饰器访问对应的系统属性数据。