ts-custom-component-initialization.md 3.4 KB
Newer Older
Z
zengyawen 已提交
1
# 自定义组件成员变量初始化
Z
zengyawen 已提交
2 3 4 5

组件的成员变量可以通过两种方式初始化:


Z
zengyawen 已提交
6 7 8 9
- 本地初始化,例如:
  ```
  @State counter: Counter = new Counter()
  ```
Z
zengyawen 已提交
10

Z
zengyawen 已提交
11 12 13 14
- 在构造组件时通过构造参数初始化,例如:
  ```
  MyComponent(counter: $myCounter)
  ```
Z
zengyawen 已提交
15 16


Z
zengyawen 已提交
17
具体允许哪种方式取决于状态变量的装饰器:
Z
zengyawen 已提交
18

Z
zengyawen 已提交
19 20 21 22 23 24 25 26 27 28 29 30 31

| 装饰器类型 | 本地初始化 | 通过构造函数参数初始化 |
| -------- | -------- | -------- |
| @State | 必须 | 可选 |
| @Prop | 禁止 | 必须 |
| @Link | 禁止 | 必须 |
| @StorageLink | 必须 | 禁止 |
| @StorageProp | 必须 | 禁止 |
| @Provide | 必须 | 可选 |
| @Consume | 禁止 | 禁止 |
| @ObjectLink | 禁止 | 必须 |
| 常规成员变量 | 推荐 | 可选 |

Z
zengyawen 已提交
32 33 34

从上表中可以看出:

Z
zengyawen 已提交
35

36
- @State变量需要本地初始化,初始化的值可以被构造参数覆盖;
Z
zengyawen 已提交
37

38
- @Prop和@Link变量必须且仅通过构造函数参数进行初始化。
Z
zengyawen 已提交
39

Z
zengyawen 已提交
40 41 42

通过构造函数方法初始化成员变量,需要遵循如下规则:

Z
zengyawen 已提交
43 44 45 46 47 48 49 50 51 52

| 从父组件中的变量(下)到子组件中的变量(右) | @State | @Link | @Prop | 常规变量 |
| -------- | -------- | -------- | -------- | -------- |
| @State | 不允许 | 允许 | 允许 | 允许 |
| @Link | 不允许 | 允许 | 不推荐 | 允许 |
| @Prop | 不允许 | 不允许 | 允许 | 允许 |
| @StorageLink | 不允许 | 允许 | 不允许 | 允许 |
| @StorageProp | 不允许 | 不允许 | 不允许 | 允许 |
| 常规变量 | 允许 | 不允许 | 不允许 | 允许 |

Z
zengyawen 已提交
53 54 55 56

从上表中可以看出:


57
- 父组件的常规变量可以用于初始化子组件的@State变量,但不能用于初始化@Link或@Prop变量。
Z
zengyawen 已提交
58

59
- 父组件的@State变量可以初始化子组件的@Prop、@Link(通过$)或常规变量,但不能初始化子组件的@State变量。
Z
zengyawen 已提交
60

61
- 父组件的@Link变量可以初始化子组件的@Link或常规变量。但是初始化子组件的@State成员是语法错误,此外不建议初始化@prop。
Z
zengyawen 已提交
62

63
- 父组件的@Prop变量可以初始化子组件的常规变量或@Prop变量,但不能初始化子组件的@State或@Link变量。
Z
zengyawen 已提交
64 65 66 67 68 69 70

- @StorageLink和@StorageProp不允许由父组件中传递到子组件。

- 除了上述规则外,还需要遵循TS的强类型规则。


## 示例
Z
zengyawen 已提交
71 72

```
T
tianyu 已提交
73 74 75 76 77 78
class ClassA {
  public a:number
  constructor(a: number) {
    this.a = a
  }
}
Z
zengyawen 已提交
79 80 81
@Entry
@Component
struct Parent {
T
tianyu 已提交
82 83 84 85 86 87 88 89 90 91 92 93 94
  @State parentState: ClassA = new ClassA(1)
  
  build() {
    Column() {
      Flex({ justifyContent: FlexAlign.Start, alignItems: ItemAlign.Center }) {
        CompA({ astate: new ClassA(2), aLink: $parentState })
      }
      Flex({ justifyContent: FlexAlign.Start, alignItems: ItemAlign.Center }) {
        CompA({ aLink: $parentState })
      }
      Flex({ justifyContent: FlexAlign.Start, alignItems: ItemAlign.Center }) {
        CompA({ astate: new ClassA(3), aLink: $parentState })
      }
Z
zengyawen 已提交
95
    }
T
tianyu 已提交
96
  }
Z
zengyawen 已提交
97 98 99 100
}

@Component
struct CompA {
T
tianyu 已提交
101 102 103 104 105 106 107
  @State aState: any = false
  @Link aLink: ClassA
  
  build() {
    Column() {
      CompB({ bLink: $aLink, bProp: this.aState })
      CompB({ bLink: $aState, bProp: false })
Z
zengyawen 已提交
108
    }
T
tianyu 已提交
109
  }
Z
zengyawen 已提交
110 111 112 113
}

@Component
struct CompB {
T
tianyu 已提交
114 115 116 117 118 119 120 121 122
  @Link bLink: ClassA
  @Prop bProp: bpplean
  
  build() {
    Flex({ justifyContent: FlexAlign.Start, alignItems: ItemAlign.Center }) {
      Text(JSON.stringify(this.bLink.a)).fontSize(30)
      Text(JSON.stringify(this.bProp)).fontSize(30).fontColor(Color.Red)
     }.margin(10)
  }
Z
zengyawen 已提交
123 124
}
```