目录
ArkTS状态管理装饰器V1
arkts早期提供给开发者使用的状态管理装饰器,对于嵌套类的观测存在诸多限制。在API12中为开发者提供了一套全新的状态管理V2(简称V2)。官方是希望后续用V2版本的装饰器取代V1的装饰器。实际上目前大部分的开发代码仍使用的是V1版本的装饰器。
装饰器类别 | 装饰器 |
---|---|
组件内装饰器 | @State、@Prop、@Link、@ObjectLink、@Provide、@Consume、@StorageProp、@StorageLink、@LocalStorageProp、@LocalStorageLink、@Watch |
类相关装饰器 | @Observed、@Track |
组件定义
@Component
@Component装饰器仅能装饰struct关键字声明的数据结构。struct被@Component装饰后具备组件化的能力,需要实现build方法描述UI,一个struct只能被一个@Component装饰。@Component可以接受一个可选的bool类型参数,用来冻结自定义组件(冻结的组件不会随@state变量更新变化UI)。
freezeWhenInactive11+
组件冻结选项。
名称 | 类型 | 必填 | 说明 |
---|---|---|---|
freezeWhenInactive | bool | 否 | 是否开启组件冻结。 |
@Component({ freezeWhenInactive: true })
struct MyComponent {
}
@Entry(通用)
修饰@Component定义的自定义组件,将其作为入口组件。
入口组件:可以作为页面路由单独显示的,可以理解为一个完整的页面,无@Entry修饰的自定义组件只是部分页面,应用只能显示完整的页面,可以通过windowStage.loadContent方法决定挂载哪一个完整页面。
@Entry可以接受一个可选的LocalStorage的参数或者一个可选的EntryOptions参数。入参见
EntryOptions10+
命名路由跳转选项。
名称 | 类型 | 必填 | 说明 |
---|---|---|---|
routeName | string | 否 | 表示作为命名路由页面的名字。 |
storage | LocalStorage | 否 | 页面级的UI状态存储。 |
useSharedStorage12+ | boolean | 否 | 是否使用LocalStorage.getShared()接口返回的LocalStorage实例对象,默认值false。 |
说明
当useSharedStorage设置为true,并且storage也被赋值时,useSharedStorage的值优先级更高。
@Entry({ routeName : 'myPage' })
@Component
struct MyComponent {
}
Component、Entry示例
@Entry
@Component
struct Index {
@State message: string = 'Hello World';
build() {
RelativeContainer() {
Text(this.message)
.id('HelloWorld')
.fontSize(50)
.fontWeight(FontWeight.Bold)
.alignRules({
center: { anchor: '__container__', align: VerticalAlign.Center },
middle: { anchor: '__container__', align: HorizontalAlign.Center }
})
}
.height('100%')
.width('100%')
}
}
@Reusable
@Reusable适用自定义组件,与@Component结合使用,标记为@Reusable的自定义组件从组件树上被移除时,组件和其对应的JSView对象都会被放入复用缓存中,后续创建新自定义组件节点时,会复用缓存区中的节点,节约组件重新创建的时间。
复用组件的时候会执行aboutToReuse方法,该方法接收一个参数,参数上挂载了自定义组件被删除前的状态变量。
组件状态管理
通过代理监听被装饰变量的变化来刷新组件的UI。
@State、@Prop、@Link装饰的变量可以监视基础变量的变化,以及复杂类型变量的单层变化,例如装饰对象时,可以监听到第一层属性指向的值的变化。当有嵌套时,是无法监听到里层属性的变化。
@State
修饰自定义组件中的属性变量,变量变化会触发自定义组件的UI刷新。修饰的变量需要初始值。
父组件调用自定义组件时可以通过同名入参传入子组件@State修饰的属性变量的值(会覆盖子组件中定义的初始值),但是父组件中的传入值变化不会导致子组件中的变量变化。如果想实现父到子的同步可以使用@Prop,想实现父子的完全同步可以使用@Link。
a.b(this.object)形式调用,不会触发UI刷新
通过a.b(this.object)形式调用时,b方法内传入的是this.object的原生对象,修改其属性,无法触发UI刷新。如下例中,通过静态方法Score.changeScore1或者this.changeScore2修改Child组件中的this.score.value时,UI不会刷新。
注意:a.b(this.object)形式调用,在@Link、@Prop、@Observed、@ObjectLink、@Provide、@Consume等装饰器中也是一样的