ts-custom-component-initialization.md 3.6 KB
Newer Older
Z
zengyawen 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 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 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114
# 自定义组件初始化

本节介绍自定义组件状态变量的初始化规则。


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


- 本地初始化,例如:
  ```
  @State counter: Counter = new Counter()
  ```

- 在构造组件时通过构造参数初始化,例如:
  ```
  MyComponent(counter: $myCounter)
  ```


具体允许哪种方式取决于状态变量的装饰器:


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


从上表中:


- **@State**变量需要本地初始化,初始化的值可以被构造参数覆盖;

- **@Prop****@Link**变量必须且仅通过构造函数参数进行初始化。


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


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


从上表中:


- 父组件的常规变量可以用于初始化子组件的**@State**变量,但不能用于初始化**@Link****@Prop**变量;

- 父组件的**@State**变量可以初始化子组件的**@Prop****@Link(通过$)**或常规变量,但不能初始化子组件的**@State**变量;

- 父组件的**@Link**变量可以初始化子组件的@Link或常规变量。但是初始化子组件的**@State**成员是语法错误,此外不建议初始化**@prop;**

- 父组件的**@Prop**变量可以初始化子组件的常规变量或**@Prop**变量,但不能初始化子组件的**@State****@Link**变量。

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

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


## 示例

```
@Entry
@Component
struct Parent {
    @State parentState: ClassA = new ClassA()
    build() {
        Row() {
            CompA({aState: new ClassA, aLink: $parentState}) // valid
            CompA({aLink: $parentState})   // valid
            CompA()                 // invalid, @Link aLink remains uninitialized
            CompA({aLink: new ClassA}) // invalid, @Link aLink must be a reference ($) to either @State or @Link variable
        }
    }
}

@Component
struct CompA {
    @State aState: boolean = false   // must initialize locally
    @Link aLink: ClassA              // must not initialize locally

    build() {
        Row() {
            CompB({bLink: $aLink,         // valid init a @Link with reference of another @Link,
                bProp: this.aState})    // valid init a @Prop with value of a @State
            CompB({aLink: $aState,  // invalid: type missmatch expected ref to ClassA, provided reference to boolean
                bProp: false})           // valid init a @Prop by constants value
        }
    }
}

@Component
struct CompB {
    @Link bLink: ClassA = new ClassA()       // invalid, must not initialize locally
    @Prop bProp: boolean = false      // invalid must not initialize locally

    build() {
        ...
    }
}
```