ts-custom-component-initialization.md 3.5 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 37 38 39

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

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

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

从上表中可以看出:


Z
zengyawen 已提交
57 58 59 60 61 62 63 64 65 66 67 68 69 70
- 父组件的常规变量可以用于初始化子组件的**@State**变量,但不能用于初始化**@Link****@Prop**变量。

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

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

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

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

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


## 示例
Z
zengyawen 已提交
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

```
@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() {
        ...
    }
}
```