#星光计划2.0# HarmonyOS ArkUI之UI状态管理(TS) 原创 精华
作者:王国菊
【本文正在参与51CTO HarmonyOS技术社区创作者激励计划-星光计划2.0】
前言
在声明式UI编程范式中,UI是应用程序状态的函数,开发人员通过修改当前应用程序状态来更新相应的UI界面。
开发框架提供了多种应用程序状态管理的能力。
状态变量装饰器
@State:组件拥有的状态属性。每当@State装饰的变量更改时,组件会重新渲染更新UI。
@Link:组件依赖于其父组件拥有的某些状态属性。每当任何一个组件中的数据更新时,另一个组件的状态都会更新,父子组件都会进行重新渲染。
@Prop:工作原理类似@Link,只是子组件所做的更改不会同步到父组件上,属于单向传递。
@state
@State装饰的变量是组件内部的状态数据,当这些状态数据被修改时,将会调用所在组件的build方法进行UI刷新。
@State状态数据具有以下特征:
支持多种类型:允许如下强类型的按值和按引用类型:class、number、boolean、string,以及这些类型的数组,即Array<class>、Array<string>、Array<boolean>、Array<number>。不允许object和any。
支持多实例:组件不同实例的内部状态数据独立。
内部私有:标记为@State的属性不能直接在组件外部修改。它的生命周期取决于它所在的组件。
需要本地初始化:必须为所有@State变量分配初始值,将变量保持未初始化可能导致框架行为未定义。
创建自定义组件时支持通过状态变量名设置初始值:在创建组件实例时,可以通过变量名显式指定@State状态属性的初始值。
复杂类型的状态属性示例
简单类型的状态属性示例
在上述示例中:
用户定义的组件MyComponent定义了@State状态变量count和title。如果count或title的值发生变化,则执行MyComponent的build方法来重新渲染组件;
EntryComponent中有多个MyComponent组件实例,第一个MyComponent内部状态的更改不会影响第二个MyComponent;
@prop
@Prop具有与@State相同的语义,但初始化方式不同。@Prop装饰的变量必须使用其父组件提供的@State变量进行初始化,允许组件内部修改@Prop变量,但上述更改不会通知给父组件,即@Prop属于单向数据绑定。
@Prop状态数据具有以下特征:
支持简单类型:仅支持简单类型:number、string、boolean;
私有:仅在组件内访问;
支持多个实例:一个组件中可以定义多个标有@Prop的属性;
创建自定义组件时将值传递给 变量进行初始化:在创建组件的新实例时,必须初始化所有@Prop变量,不支持在组件内部进行初始化。(创建新组件实例时,必须初始化其所有@Prop变量。)
示例
在上述示例中,当按“+1”或“-1”按钮时,父组件状态发生变化,重新执行build方法,此时将创建一个新的CountDownComponent组件。父组件的countDownStartValue状态属性被用于初始化子组件的@Prop变量。当按下子组件的“Try again”按钮时,其@Prop变量count将被更改,这将导致CountDownComponent重新渲染。但是,count值的更改不会影响父组件的countDownStartValue值。
@link
@Link装饰的变量可以和父组件的@State变量建立双向数据绑定:
支持多种类型:@Link变量的值与@State变量的类型相同,即class、number、string、boolean或这些类型的数组;
私有:仅在组件内访问;
单个数据源:初始化@Link变量的父组件的变量必须是@State变量;
双向通信:子组件对@Link变量的更改将同步修改父组件的@State变量;
创建自定义组件时需要将变量的引用传递给@Link变量:在创建组件的新实例时,必须使用命名参数初始化所有@Link变量。@Link变量可以使用@State变量或@Link变量的引用进行初始化。@State变量可以通过’$'操作符创建引用。(变量不能在组件内部进行初始化。)
示例
@Link和@State、@Prop结合使用示例
上述示例中,ParentView包含ChildA和ChildB两个子组件,ParentView的状态变量counter分别初始化ChildA和ChildB:
- ChildB使用@Link建立双向状态绑定;
- 当ChildB修改counterRef状态变量值时,该更改将同步到ParentView和ChildA共享;
- ChildA使用@Prop建立从ParentView到自身的单向状态绑定;
- 当ChildA修改状态时,ChildA将重新渲染,但该更改不会传达给ParentView和ChildB。
更多原创内容请关注:深开鸿技术团队
入门到精通、技巧到案例,系统化分享HarmonyOS开发技术,欢迎投稿和订阅,让我们一起携手前行共建鸿蒙生态。
很不错的内容,从原理上讲开了,很深入的内容