arkts-restrictions-and-extensions.md 4.7 KB
Newer Older
T
tianyu 已提交
1 2 3 4
# 使用限制与扩展

## 在生成器函数中的使用限制

L
luoying_ace_admin 已提交
5
ArkTS语言的使用在生成器函数中存在一定的限制:
T
tianyu 已提交
6

L
luoying_ace_admin 已提交
7 8 9 10
- 表达式仅允许在字符串(${expression})、if/else条件语句、ForEach的参数以及组件的参数中使用。

- 任何表达式都不能导致应用程序中状态变量(@State、@Link、@Prop)的改变,否则会造成未定义和潜在不稳定的框架行为。

T
tianyu 已提交
11 12
- 生成器函数内部不能有局部变量。

L
luoying_ace_admin 已提交
13
上述限制都不适用于事件方法(如onClick)的匿名函数实现。
T
tianyu 已提交
14 15 16

## 变量的双向绑定

L
luoying_ace_admin 已提交
17
ArkTS支持通过$$双向绑定变量,通常应用于状态值频繁改变的变量。
T
tianyu 已提交
18 19

- 当前$$支持基础类型变量,以及@State、@Link和@Prop装饰的变量。
L
luoying_ace_admin 已提交
20 21
- 当前$$仅支持[bindPopup](../reference/arkui-ts/ts-universal-attributes-popup.md)属性方法的show参数,[Radio](../reference/arkui-ts/ts-basic-components-radio.md)组件的checked属性,[Refresh](../reference/arkui-ts/ts-container-refresh.md)组件的refreshing参数。
- $$绑定的变量变化时,仅渲染刷新当前组件,提高渲染速度。
T
tianyu 已提交
22 23 24 25 26

```ts
// xxx.ets
@Entry
@Component
L
luoying_ace_admin 已提交
27 28
struct bindPopupPage {
  @State customPopup: boolean = false
T
tianyu 已提交
29

L
luoying_ace_admin 已提交
30 31 32 33 34 35 36 37 38 39 40 41 42
  build() {
    Column() {
      Button('Popup')
        .margin(20)
        .onClick(() => {
          this.customPopup = !this.customPopup
        })
        .bindPopup($$this.customPopup, {
          message: "showPopup"
        })
    }
  }
}
T
tianyu 已提交
43 44
```

Y
yamila 已提交
45 46
![popup](figures/popup.gif)

L
luoying_ace_admin 已提交
47
## 状态变量数据类型声明使用限制
T
tianyu 已提交
48

L
luoying_ace_admin 已提交
49
@State、@Provide、 @Link和@Consume四种状态变量的数据类型声明只能由简单数据类型或引用数据类型的其中一种构成。
T
tianyu 已提交
50 51 52 53 54 55 56

示例:

```ts
// xxx.ets
@Entry
@Component
L
luoying_ace_admin 已提交
57
struct IndexPage {
T
tianyu 已提交
58 59 60 61 62 63
  //错误写法: @State message: string | Resource = 'Hello World'
  @State message: string = 'Hello World'

  build() {
    Row() {
      Column() {
L
luoying_ace_admin 已提交
64
        Text(`${this.message}`)
T
tianyu 已提交
65 66 67 68 69 70 71 72
          .fontSize(50)
          .fontWeight(FontWeight.Bold)
      }
      .width('100%')
    }
    .height('100%')
  }
}
Y
yamila 已提交
73 74
```

L
luoying_ace_admin 已提交
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
![hello](figures/hello.PNG)

## 自定义组件成员变量初始化的方式与约束

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

- 本地初始化:

  ```ts
  @State counter: Counter = new Counter()
  ```
- 在构造组件时通过构造参数初始化:

  ```ts
  MyComponent({counter: $myCounter})
  ```

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

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

从上表中可以看出:

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

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

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

W
wangshuainan 已提交
114 115 116 117 118 119 120 121
| 从父组件中的变量(下)到子组件中的变量(右) | @State | @Link  | @Prop  | 常规变量 |
| -------------------------------------------- | ------ | ------ | ------ | -------- |
| @State                                       | 不允许 | 允许   | 允许   | 允许     |
| @Link                                        | 不允许 | 允许   | 不推荐 | 允许     |
| @Prop                                        | 不允许 | 不允许 | 允许   | 允许     |
| @StorageLink                                 | 不允许 | 允许   | 不允许 | 不允许   |
| @StorageProp                                 | 不允许 | 不允许 | 不允许 | 允许     |
| 常规变量                                     | 允许   | 不允许 | 不允许 | 允许     |
L
luoying_ace_admin 已提交
122 123 124 125 126 127 128 129 130 131 132 133 134 135

从上表中可以看出:

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

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

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

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

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

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