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

```
@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
96
            CompB({aLink: $aState,  // invalid: type mismatch expected ref to ClassA, provided reference to boolean
Z
zengyawen 已提交
97 98 99 100 101 102 103 104 105 106 107 108 109 110 111
                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() {
        ...
    }
}
```