鸿蒙开发采用的声明式UI,利用状态驱动UI的更新。其中@State被称作装饰器,是一种状态管理的方式。
状态:指的是被装饰器装饰的驱动视图更新的数据。
视图:是指用户看到的UI渲染出来的界面。
之所以成为双向绑定可以这样理解,在视图上的点击事件中去更改状态数据,反过来监听状态的视图也发生相应的数据改变。
@State可以作用到Object对象、数组、number、string、class、boolean、enum等类型。
但是,监听的嵌套对象的属性或者嵌套的数组内属性的改变不能引起视图的改变。
如string,通过点击可以发现在改变message字符串值时UI渲染的内容也发生了改变
class Person {
name: string
age:number
constructor(name:string,age:number) {
this.name = name
this.age = age
}
}
@Entry
@Component
struct StatePage {
@State p:Person = new Person('Jack',20)
build() {
Column() {
Text(this.p.name+':'+this.p.age)
.fontSize(30)
.fontColor('#36D')
.onClick(() => {
this.p.age = 21
})
}
.width('100%')
.height('100%')
}
}
定义一个Person类,我们用@State装饰器监听成员变量p,那么在点击方法中设置p的年龄为21,那么相应的Text内容也发生了改变。
class Person {
name: string
age:number
girlFriend:Person
constructor(name:string,age:number,gf?:Person) {
this.name = name
this.age = age
this.girlFriend = gf
}
}
@Entry
@Component
struct StatePage {
@State p:Person = new Person('Jack',20,new Person('rose',18))
build() {
Column() {
Text(this.p.girlFriend.name+':'+this.p.girlFriend.age)
.fontSize(30)
.fontColor('#36D')
.onClick(() => {
this.p.girlFriend.age = 19
console.log('person girl friend age = ' + this.p.girlFriend.age)
})
}
.width('100%')
.height('100%')
}
}
我定义了一个Person类,并且里边有个嵌套的Person属性girlFriend。当我们点击了Text,改变监听对象p的girlfriend的属性,consolelog显示数据发生了改变,但是UI并没有发生改变
当然,数组也是同样的,如果是对单层的数组进行增删是可以监听到的。如果是嵌套数组,对内部数组进行操作,也是无法监听到的。
如图所示,如果不给初始化值,编译器会报错,提示被这几个装饰器修饰的必须进行本地初始化。