ts-component-states-state.md 3.4 KB
Newer Older
Z
zengyawen 已提交
1
# @State
Z
zengyawen 已提交
2

T
tianyu 已提交
3
@State装饰的变量是组件内部的状态数据,当这些状态数据被修改时,将会调用所在组件的build方法进行UI刷新,只能监听第一层数据的改变,内层数据的改变@State监听不到,无法触发build生命周期。
Z
zengyawen 已提交
4

5
@State状态数据具有以下特征:
Z
zengyawen 已提交
6 7


8
- 支持多种类型:允许class、number、boolean、string强类型的按值和按引用类型。允许这些强类型构成的数组,即Array<class>、Array<string>、Array<boolean>、Array<number>。不允许object和any。
Z
zengyawen 已提交
9

10
- 支持多实例:组件不同实例的内部状态数据独立。
Z
zengyawen 已提交
11

12
- 内部私有:标记为@State的属性是私有变量,只能在组件内访问。
Z
zengyawen 已提交
13

14
- 需要本地初始化:必须为所有@State变量分配初始值,将变量保持未初始化可能导致框架行为未定义。
Z
zengyawen 已提交
15

16
- 创建自定义组件时支持通过状态变量名设置初始值:在创建组件实例时,可以通过变量名显式指定@State状态属性的初始值。
Z
zengyawen 已提交
17 18 19


## 简单类型的状态属性示例
Z
zengyawen 已提交
20

H
HelloCrease 已提交
21 22
```ts
// xxx.ets
Z
zengyawen 已提交
23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
@Entry
@Component
struct MyComponent {
    @State count: number = 0
    // MyComponent provides a method for modifying the @State status data member.
    private toggleClick() {
        this.count += 1
    }

    build() {
        Column() {
            Button() {
                Text(`click times: ${this.count}`)
                    .fontSize(10)
            }.onClick(this.toggleClick.bind(this))
        }
    }
}
```

T
tianyu 已提交
43
![@state1](figures/@state1.gif)
Z
zengyawen 已提交
44 45

## 复杂类型的状态变量示例
Z
zengyawen 已提交
46

H
HelloCrease 已提交
47
```ts
Z
zengyawen 已提交
48
// Customize the status data class.
H
HelloCrease 已提交
49
// xxx.ets
Z
zengyawen 已提交
50 51 52 53 54 55 56 57 58 59 60 61
class Model {
    value: string
    constructor(value: string) {
        this.value = value
    }
}

@Entry
@Component
struct EntryComponent {
    build() {
        Column() {
62 63
            MyComponent({count: 1, increaseBy: 2})  // MyComponent1 in this document            
            MyComponent({title: {value: 'Hello, World 2'}, count: 7})   //MyComponent2 in this document
Z
zengyawen 已提交
64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93
        }
    }
}

@Component
struct MyComponent {
    @State title: Model = {value: 'Hello World'}
    @State count: number = 0
    private toggle: string = 'Hello World'
    private increaseBy: number = 1

    build() {
        Column() {
            Text(`${this.title.value}`).fontSize(30)
            Button() {
                Text(`Click to change title`).fontSize(20).fontColor(Color.White)
            }.onClick(() => {
                this.title.value = (this.toggle == this.title.value) ? 'Hello World' : 'Hello UI'
            }) // Modify the internal state of MyComponent using the anonymous method.

            Button() {
                Text(`Click to increase count=${this.count}`).fontSize(20).fontColor(Color.White)
            }.onClick(() => {
                this.count += this.increaseBy
            }) // Modify the internal state of MyComponent using the anonymous method.
        }
    }
}
```

T
tianyu 已提交
94
![@state1](figures/@state.png)
Z
zengyawen 已提交
95

Z
zengyawen 已提交
96 97 98
在上述示例中:


99
- 用户定义的组件MyComponent定义了@State状态变量count和title。如果count或title的值发生变化,则执行MyComponent的build方法来重新渲染组件;
Z
zengyawen 已提交
100

101
- EntryComponent中有多个MyComponent组件实例,第一个MyComponent内部状态的更改不会影响第二个MyComponent;
Z
zengyawen 已提交
102

103
- 创建MyComponent实例时通过变量名给组件内的变量进行初始化,如:
H
HelloCrease 已提交
104
  ```ts
Z
zengyawen 已提交
105 106
  MyComponent({title: {value: 'Hello, World 2'}, count: 7})
  ```