arkts-restrictions-and-extensions.md 11.2 KB
Newer Older
E
ester.zhou 已提交
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
# Restrictions and Extensions

## Restrictions on Using ArkTS in Generators

ArkTS has the following restrictions on generators:

- Expressions can be used only in character strings (${expression}), **if/else** statements, **ForEach** parameters, and component parameters.

- No expressions should cause any application state variables (that is, variables decorated by **@State**, **@Link**, and **@Prop**) to change. Otherwise, undefined and potentially unstable framework behavior may occur.

- The generator function cannot contain local variables.

None of the above restrictions applies to anonymous function implementations of event methods (such as **onClick**).

## Two-Way Binding of Variables

ArkTS supports two-way binding through **$$**, which is usually used for variables whose state values change frequently.

- **$$** supports variables of primitive types and variables decorated by **@State**, **@Link**, or **@Prop**.
- **$$** supports only the **show** parameter of the **[bindPopup](../reference/arkui-ts/ts-universal-attributes-popup.md)** attribute method, the **checked** attribute of the **[\<Radio>](../reference/arkui-ts/ts-basic-components-radio.md)** component, and the **refreshing** parameter of the **[\<Refresh>](../reference/arkui-ts/ts-container-refresh.md)** component.
- When the variable bound to **$$** changes, only the current component is rendered, which improves the rendering speed.

```ts
// xxx.ets
@Entry
@Component
struct bindPopupPage {
  @State customPopup: boolean = false

  build() {
    Column() {
      Button('Popup')
        .margin(20)
        .onClick(() => {
          this.customPopup = !this.customPopup
        })
        .bindPopup($$this.customPopup, {
          message: "showPopup"
        })
    }
  }
}
```

![popup](figures/popup.gif)

## Restrictions on Data Type Declarations of State Variables

E
ester.zhou 已提交
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
1. The data types of state variables decorated by state decorators must be explicitly declared. They cannot be declared as **any** or **Date**.

    Example:

    ```ts
    // xxx.ets
    @Entry
    @Component
    struct DatePickerExample {
      // Incorrect: @State isLunar: any = false
      @State isLunar: boolean = false
      // Incorrect: @State selectedDate: Date = new Date('2021-08-08')
      private selectedDate: Date = new Date('2021-08-08')

      build() {
        Column() {
          Button('Switch Calendar')
            .margin({ top: 30 })
            .onClick(() => {
              this.isLunar = !this.isLunar
            })
          DatePicker({
            start: new Date('1970-1-1'),
            end: new Date('2100-1-1'),
            selected: this.selectedDate
          })
            .lunar(this.isLunar)
            .onChange((value: DatePickerResult) => {
              this.selectedDate.setFullYear(value.year, value.month, value.day)
              console.info('select current date is: ' + JSON.stringify(value))
            })

        }.width('100%')
E
ester.zhou 已提交
82 83
      }
    }
E
ester.zhou 已提交
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 115 116 117
    ```

    ![datePicker](../../application-dev/reference/arkui-ts/figures/datePicker.gif)

2. The data type declaration of the **@State**, **@Provide**, **@Link**, or **@Consume** decorated state variables can consist of only one of the primitive data types or reference data types.

    The **Length**, **ResourceStr**, and **ResourceColor** types are combinations of primitive data types or reference data types. Therefore, they cannot be used by the aforementioned types of state variables.
    For details about the definitions of **Length**, **ResourceStr**, and **ResourceColor**, see [Types](../../application-dev/reference/arkui-ts/ts-types.md).

    Example:

    ```ts
    // xxx.ets
    @Entry
    @Component
    struct IndexPage {
      // Incorrect: @State message: string | Resource = 'Hello World'
      @State message: string = 'Hello World'
      // Incorrect: @State message: ResourceStr = $r('app.string.hello')
      @State resourceStr: Resource = $r('app.string.hello')

      build() {
        Row() {
          Column() {
            Text(`${this.message}`)
              .fontSize(50)
              .fontWeight(FontWeight.Bold)
          }
          .width('100%')
        }
        .height('100%')
      }
    }
    ```
E
ester.zhou 已提交
118

E
ester.zhou 已提交
119
    ![hello](figures/hello.PNG)
E
ester.zhou 已提交
120

E
ester.zhou 已提交
121
## Initialization Rules and Restrictions of Custom Components' Member Variables
E
ester.zhou 已提交
122 123 124 125 126 127 128 129 130 131 132 133 134 135

The member variables of a component can be initialized in either of the following ways:

- Local initialization:

  ```ts
  @State counter: Counter = new Counter()
  ```
- Initialization using constructor parameters:

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

E
ester.zhou 已提交
136
The allowed method depends on the decorator of the state variable, as described in the following table.
E
ester.zhou 已提交
137 138 139 140 141 142 143 144

| Decorator       | Local Initialization| Initialization Using Constructor Parameters|
| ------------ | ----- | ----------- |
| @State       | Mandatory   | Optional         |
| @Prop        | Forbidden   | Mandatory         |
| @Link        | Forbidden   | Mandatory         |
| @StorageLink | Mandatory   | Forbidden         |
| @StorageProp | Mandatory   | Forbidden         |
E
ester.zhou 已提交
145 146
| @LocalStorageLink | Mandatory   | Forbidden         |
| @LocalStorageProp | Mandatory   | Forbidden         |
E
ester.zhou 已提交
147 148 149 150 151 152 153 154 155 156 157 158 159
| @Provide     | Mandatory   | Optional         |
| @Consume     | Forbidden   | Forbidden         |
| @ObjectLink  | Forbidden   | Mandatory         |
| Normal member variable      | Recommended   | Optional         |

As indicated by the preceding table:

- The **@State** decorated variables must be initialized locally. Their initial values can be overwritten by the constructor parameters.

- The **@Prop** and **@Link** decorated variables must be initialized only by constructor parameters.

Comply with the following rules when using constructors to initialize member variables:

E
ester.zhou 已提交
160 161 162 163 164 165 166 167 168
| **From the Variable in the Parent Component (Right) to the Variable in the Child Component (Below)**| **regular** | **@State** | **@Link** | **@Prop** | **@Provide** | **@Consume** | **@ObjectLink** |
|---------------------------------|----------------------------|------------|-----------|-----------|--------------|--------------|------------------|
| **regular**                    | Supported                        | Supported        | Supported       | Supported       | Not supported           | Not supported           | Supported              |
| **@State**                     | Supported                        | Supported        | Supported       | Supported       | Supported          | Supported          | Supported              |
| **@Link**                      | Not supported                         | Supported (1)     | Supported (1)    | Supported (1)    | Supported (1)       | Supported (1)       | Supported (1)           |
| **@Prop**                      | Supported                        | Supported        | Supported       | Supported       | Supported          | Supported          | Supported              |
| **@Provide**                   | Supported                        | Supported        | Supported       | Supported       | Supported          | Supported          | Supported              |
| **@Consume**                   | Not supported                         | Not supported         | Not supported        | Not supported        | Not supported           | Not supported           | Not supported               |
| **@ObjectLink**                | Not supported                         | Not supported     | Not supported        | Not supported        | Not supported           | Not supported           | Not supported               |
E
ester.zhou 已提交
169

E
ester.zhou 已提交
170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188
| **From the Variable in the Parent Component (Right) to the Variable in the Child Component (Below)**| **@StorageLink** | **@StorageProp** | **@LocalStorageLink** | **@LocalStorageProp** |
|------------------|------------------|------------------|-----------------------|------------------------|
| **regular**                   | Supported              | Not supported               | Not supported                    | Not supported             |
| **@State**                    | Supported              | Supported              | Supported                   | Supported                    |
| **@Link**                     | Supported (1)           | Supported (1)           | Supported (1)                | Supported (1)                 |
| **@Prop**                     | Supported              | Supported              | Supported                   | Supported                    |
| **@Provide**                  | Supported              | Supported              | Supported                   | Supported                    |
| **@Consume**                  | Not supported            | Not supported             | Not supported                 | Not supported                  |
| **@ObjectLink**               | Not supported            | Not supported             | Not supported                 | Not supported                  |

> **NOTE**
>
> **Supported (1)**: The dollar sign ($) must be used, for example, **this.$varA**.
>
> **regular**: refers to a regular variable that is not decorated by any decorator.

As indicated by the preceding tables:

- The **@ObjectLink** decorated variable cannot be directly initialized from a decorated variable in the parent component. The source of the parent component must be an array item or object attribute decorated by **@State**, **@Link**, **@Provide**, **@Consume**, or **@ObjectLink**.
E
ester.zhou 已提交
189

E
ester.zhou 已提交
190
- The regular variables of the parent component can be used to initialize the **@State** variable of the child component, but cannot be used to initialize the **@Link**, **@Consume**, and **@ObjectLink** variables.
E
ester.zhou 已提交
191

E
ester.zhou 已提交
192
- The **@State** variable of the parent component can be used to initialize the **@Prop**, **@Link** (through **$**), or regular variables of the child component, but cannot be used to initialize the **@Consume** variable.
E
ester.zhou 已提交
193

E
ester.zhou 已提交
194
- The **@Link** variable of the parent component cannot be used to initialize the **@Consume** and **@ObjectLink** variables of the child component.
E
ester.zhou 已提交
195

E
ester.zhou 已提交
196
- The **@Prop** variable of the parent component cannot be used to initialize the **@Consume** and **@ObjectLink** variables of the child component.
E
ester.zhou 已提交
197

E
ester.zhou 已提交
198
- **@StorageLink**, **@StorageProp**, **@LocalStorageLink**, and **@LocalStorageProp** variables cannot be initialized from the parent component.
E
ester.zhou 已提交
199 200

- In addition to the preceding rules, the TypeScript strong type rules need to be followed.
E
ester.zhou 已提交
201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234

Example:
```ts
@Entry
@Component
struct Parent {
  message: string = "Hello World"
  build() {
    Column() {
      Child({
        stateMessage: this.message,
        /* ArkTS:ERROR The regular property 'message' cannot be assigned  
           to the @Link property 'linkMessage'.*/
        linkMessage: this.$message
      })
    }
    .width('100%')
  }
}

@Component
struct Child {
  @State stateMessage: string = "Hello World"
  @Link linkMessage: string
  build() {
    Column() {
      Text(this.stateMessage)
        .fontSize(50)
        .fontWeight(FontWeight.Bold)
    }
    .width('100%')
  }
}
```
E
ester.zhou 已提交
235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257

## Restrictions on Naming Custom Components, Classes, and Functions

The name of a custom component, class, or function cannot be the same as any system component name.

Example:

```
// Rect.ets
export class Rect {
  constructor(){}
}
// Index.ets
// ERROR: The module name 'Rect' can not be the same as the inner component name.
import { Rect } from './Rect';
@Entry
@Component
struct Index {
  build() {
    
  }
}
```