状态管理
状态管理之v1
- @State 管理组件内部状态
- @Prop 用于父组件传递数据,子组件不能修改
- @Link 实现双向绑定,子组件可以修改
- @Provide 与 @Consume 则提供了全局共享状态的机制。
- @Observed:声明可观察对象,
- @ObjectLink:用于实现双向数据绑定,允许子组件直接修改父组件的对象,适合复杂对象的双向传递。
- @LocalStorage: 页面级UI状态存储,装饰器有@LocalStorageProp和@LocalStorageLink
- @AppStorage: 应用全局的UI状态存储,装饰器有@StorageProp和@StorageLink
- @PersistentStorage: 持久化存储UI状态,需要依赖AppStorage
- @Environment: 设备环境查询,需要依赖AppStorage
- @Watch:状态变量更改通知
- $$语法:内置组件双向同步
- @Track:class对象属性级更新
@LocalStorage
- 应用程序可以创建多个LocalStorage实例,LocalStorage实例可以在页面内共享,也可以通过getShared接口,实现跨页面、UIAbility实例内共享。
- 组件树的根节点,即被@Entry装饰的@Component,可以被分配一个LocalStorage实例,此组件的所有子组件实例将自动获得对该LocalStorage实例的访问权限。
- @Component装饰的组件既可以自动继承来自父组件的LocalStorage实例,也可以传入指定的LocalStorage的实例。
- LocalStorage中的所有属性都是可变的。
LocalStorageLink的框架行为
- 当@LocalStorageLink(key)装饰的数值改变被观察到时,修改将被同步回LocalStorage对应属性键值key的属性中。
- LocalStorage中属性键值key对应的数据一旦改变,属性键值key绑定的所有的数据(包括双向@LocalStorageLink和单向@LocalStorageProp)都将同步修改。
- 当@LocalStorageLink(key)装饰的数据本身是状态变量,它的改变不仅仅会同步回LocalStorage中,还会引起所属的自定义组件的重新渲染。
LocalStorageProp的框架行为
- 被@LocalStorageProp装饰的变量的值的变化不会同步回LocalStorage里。
- @LocalStorageProp装饰的变量变化会使当前自定义组件中关联的组件刷新。
- LocalStorage(key)中值的变化会引发所有被@LocalStorageProp对应key装饰的变量的变化,会覆盖@LocalStorageProp本地的改变。
LocalStorage使用场景
- 可以在应用逻辑使用LocalStorage
- 可以从UI内部使用 或者 自定义组件外使用
- 根结点可通过@Entry来接收 LocalStorage ,子节点可通过构造参数来传递 LocalStorage
- 可以从UIAbility共享到一个或多个视图(关键api:
windowStage.loadContent
和getShared()
)- LocalStorageLink 的双向同步
- LocalStorageProp 的单向同步
@AppStorage
- AppStorage是在应用启动的时候会被创建的单例。它的目的是为了提供应用状态数据的中心存储,这些状态数据在应用级别都是可访问的。AppStorage将在应用运行过程保留其属性。属性通过唯一的键字符串值访问。
- AppStorage可以和UI组件同步,且可以在应用业务逻辑中被访问。
- AppStorage支持应用的主线程内多个UIAbility实例间的状态共享。
StorageLink的框架行为
- 当@StorageLink(key)装饰的数值改变被观察到时,修改将被同步回AppStorage对应属性键值key的属性中。
- AppStorage中属性键值key对应的数据一旦改变,属性键值key绑定的所有的数据(包括双向@StorageLink和单向@StorageProp)都将同步修改。
- 当@StorageLink(key)装饰的数据本身是状态变量,它的改变不仅仅会同步回AppStorage中,还会引起所属的自定义组件的重新渲染。
StorageProp的框架行为
- 当@StorageProp(key)装饰的数值改变被观察到时,修改不会被同步回AppStorage对应key的属性中。
- 当前@StorageProp(key)单向绑定的数据会被修改,即仅限于当前组件的私有成员变量改变,其他绑定该key的数据不会同步改变。
- 当@StorageProp(key)装饰的数据本身是状态变量,它的改变虽然不会同步回AppStorage中,但是会引起所属的自定义组件重新渲染。
- 当AppStorage中key对应的属性发生改变时,会同步给所有@StorageProp(key)装饰的数据,@StorageProp(key)本地的修改将被覆盖。
AppStorage的使用场景
- 可以在应用逻辑使用AppStorage
- 可以从UI内部使用 AppStorage
- 应用的主线程内多个UIAbility实例间的状态共享
- StorageProp 的单向同步
- StorageLink 的双向同步
@PersistentStorage
- PersistentStorage将选定的AppStorage属性保留在设备磁盘上。(关键api:
PersistentStorage.persistProp('aProp', 47);
)- UI和业务逻辑不直接访问PersistentStorage中的属性,所有属性访问都是对AppStorage的访问
- PersistentStorage和AppStorage中的属性建立双向同步。
@Environment
- 开发者如果需要应用程序运行的设备的环境参数,以此来作出不同的场景判断,比如多语言,深浅色模式等,需要用到Environment设备环境查询。
- Environment是ArkUI框架在应用程序启动时创建的单例对象。它为AppStorage提供了一系列描述应用程序运行状态的属性。Environment的所有属性都是不可变的(即应用不可写入),所有的属性都是简单类型。
- Environment提供了读取系统某些环境变量的能力,具体见Environment内置参数,并将其值写入AppStorage里,所以开发者需要通过AppStorage才能获取环境变量的值。
- 关键api:
Environment.envProp('languageCode', 'en');
Environment内置参数
键 | 数据类型 | 描述 |
---|---|---|
accessibilityEnabled | boolean | 获取无障碍屏幕读取是否启用。 |
colorMode | ColorMode | 色彩模型类型:选项为ColorMode.LIGHT: 浅色,ColorMode.DARK: 深色。 |
fontScale | number | 字体大小比例。开发者需要配置configuration使fontScale跟随系统变化 |
fontWeightScale | number | 字体粗细程度。 |
layoutDirection | LayoutDirection | 布局方向类型:包括LayoutDirection.LTR: 从左到右,LayoutDirection.RTL: 从右到左。 |
languageCode | string | 当前系统语言值,取值必须为小写字母, 例如zh。 |
@Watch
- @Watch提供了状态变量的监听能力,@Watch仅能监听到可以观察到的变化。
- @Watch应用于对状态变量的监听。如果开发者需要关注某个状态变量的值是否改变,可以使用@Watch为状态变量设置回调函数。
- @Watch在ArkUI框架内部判断数值有无更新使用的是严格相等(===)
Watch的使用场景
- 建议@State、@Prop、@Link等装饰器在@Watch装饰器之前,以保持整体风格的一致。
@State @Watch('change') num: number = 10;
change() {
console.log(`xxx`);
}
$$语法
- 为系统内置组件提供TS变量的引用,使得TS变量和系统内置组件的内部状态保持同步。
- 用于@Builder装饰器的按引用传递参数
- $$支持基础类型变量,以及@State、@Link和@Prop装饰的变量。
$$ 使用场景
// xxx.ets
@Entry
@Component
struct TextInputExample {
@State text: string = ''
controller: TextInputController = new TextInputController()
build() {
Column({ space: 20 }) {
Text(this.text)
TextInput({ text: $$this.text, placeholder: 'input your word...', controller: this.controller })
.placeholderColor(Color.Grey)
.placeholderFont({ size: 14, weight: 400 })
.caretColor(Color.Blue)
.width(300)
}.width('100%').height('100%').justifyContent(FlexAlign.Center)
}
}
@Track
- @Track应用于class对象的属性级更新。@Track装饰的属性变化时,只会触发该属性关联的UI更新。
- @Track是class对象的属性装饰器。当一个class对象是状态变量时,@Track装饰的属性发生变化,只会触发该属性关联的UI更新
- 如果class类中使用了@Track装饰器,则未被@Track装饰器装饰的属性不能在UI中使用,如果使用,会发生运行时报错。
参考资料:状态管理(V1)