1# 基本UI描述 2 3ArkTS通过装饰器@Component和@Entry装饰struct关键字声明的数据结构,构成一个自定义组件。自定义组件中提供了一个build函数,开发者需在该函数内以链式调用的方式进行基本的UI描述,UI描述的方法请参考[UI描述规范](#ui描述规范)。 4 5## 基本概念 6 7- struct:自定义组件可以基于struct实现,不能有继承关系,对于struct的实例化,可以省略new。 8 9- 装饰器:装饰器给被装饰的对象赋予某一种能力,其不仅可以装饰类或结构体,还可以装饰类的属性。多个装饰器可以叠加到目标元素上,定义在同一行中或者分开多行,推荐分开多行定义。 10 11 ```ts 12 @Entry 13 @Component 14 struct MyComponent { 15 } 16 ``` 17 18- build函数:自定义组件必须定义build函数,并且禁止自定义构造函数。build函数满足Builder构造器接口定义,用于定义组件的声明式UI描述。 19 20 ```ts 21 interface Builder { 22 build: () => void 23 } 24 ``` 25 26- @Component:装饰struct,结构体在装饰后具有基于组件的能力,需要实现build方法来创建UI。 27 28- @Entry: 装饰struct,组件被装饰后作为页面的入口,页面加载时将被渲染显示。 29 30- @Preview:装饰struct, 用@Preview装饰的自定义组件可以在DevEco Studio的预览器上进行实时预览,加载页面时,将创建并显示@Preview装饰的自定义组件。 31 32 > **说明:** 在单个源文件中,最多可以使用10个@Preview装饰自定义组件,更多说明请参考[查看ArkTS组件预览效果](https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ohos-previewing-app-service-0000001218760596#section146052489820)。 33 34- 链式调用:以 "." 链式调用的方式配置UI组件的属性方法、事件方法等。 35 36## UI描述规范 37 38### 无参数构造配置 39 40如果组件的接口定义中不包含必选构造参数,组件后面的“()”中不需要配置任何内容。例如,Divider组件不包含构造参数: 41 42```ts 43Column() { 44 Text('item 1') 45 Divider() 46 Text('item 2') 47} 48``` 49 50### 有参数构造配置 51 52如果组件的接口定义中包含构造参数,则在组件后面的“()”中可配置相应参数,参数可以使用常量进行赋值。 53 54例如: 55 56- Image组件的必选参数src: 57 58 ```ts 59 Image('https://xyz/test.jpg') 60 ``` 61 62- Text组件的参数content,该参数非必选,即配置或不配置均可: 63 64 ```ts 65 Text('test') 66 ``` 67 68变量或表达式也可以用于参数赋值,其中表达式返回的结果类型必须满足参数类型要求,变量的定义详见[页面级变量的状态管理](arkts-state-mgmt-page-level.md)与[应用级变量的状态管理](arkts-state-mgmt-application-level.md)。例如,设置变量或表达式来构造Image和Text组件的参数: 69 70```ts 71Image(this.imagePath) 72Image('https://' + this.imageUrl) 73Text(`count: ${this.count}`) 74``` 75 76### 属性配置 77 78使用属性方法配置组件的属性,属性方法紧随组件,并用"."运算符连接。 79 80- 配置Text组件的字体大小属性: 81 82 ```ts 83 Text('test') 84 .fontSize(12) 85 ``` 86 87- 使用"."运算符进行链式调用并同时配置组件的多个属性,如下所示: 88 89 ```ts 90 Image('test.jpg') 91 .alt('error.jpg') 92 .width(100) 93 .height(100) 94 ``` 95 96- 除了直接传递常量参数外,还可以传递变量或表达式,如下所示: 97 98 ```ts 99 Text('hello') 100 .fontSize(this.size) 101 Image('test.jpg') 102 .width(this.count % 2 === 0 ? 100 : 200) 103 .height(this.offset + 100) 104 ``` 105 106- 对于系统内置组件,框架还为其属性预定义了一些[枚举类型](../reference/arkui-ts/ts-appendix-enums.md)供开发人员调用,枚举类型可以作为参数传递,且必须满足参数类型要求。例如,可以按以下方式配置Text组件的颜色和字体属性: 107 108 ```ts 109 Text('hello') 110 .fontSize(20) 111 .fontColor(Color.Red) 112 .fontWeight(FontWeight.Bold) 113 ``` 114 115### 事件配置 116 117通过事件方法可以配置组件支持的事件,事件方法紧随组件,并用"."运算符连接。 118 119- 使用lambda表达式配置组件的事件方法: 120 121 ```ts 122 Button('add counter') 123 .onClick(() => { 124 this.counter += 2 125 }) 126 ``` 127 128- 使用匿名函数表达式配置组件的事件方法,要求使用bind,以确保函数体中的this引用包含的组件: 129 130 ```ts 131 Button('add counter') 132 .onClick(function () { 133 this.counter += 2 134 }.bind(this)) 135 ``` 136 137- 使用组件的成员函数配置组件的事件方法: 138 139 ```ts 140 myClickHandler(): void { 141 this.counter += 2 142 } 143 144 ... 145 146 Button('add counter') 147 .onClick(this.myClickHandler.bind(this)) 148 ``` 149 150### 子组件配置 151 152对于支持子组件配置的组件,例如容器组件,在"{ ... }"里为组件添加子组件的UI描述。Column、Row、Stack、Grid、List等组件都是容器组件。 153 154- 以下是简单的Column示例: 155 156 ```ts 157 Column() { 158 Text('Hello') 159 .fontSize(100) 160 Divider() 161 Text(this.myText) 162 .fontSize(100) 163 .fontColor(Color.Red) 164 } 165 ``` 166 167- 容器组件之间也可以互相嵌套,实现相对复杂的多级嵌套效果: 168 169 ```ts 170 Column() { 171 Row() { 172 Image('test1.jpg') 173 .width(100) 174 .height(100) 175 Button('click +1') 176 .onClick(() => { 177 console.info('+1 clicked!') 178 }) 179 } 180 181 Divider() 182 Row() { 183 Image('test2.jpg') 184 .width(100) 185 .height(100) 186 Button('click +2') 187 .onClick(() => { 188 console.info('+2 clicked!') 189 }) 190 } 191 192 Divider() 193 Row() { 194 Image('test3.jpg') 195 .width(100) 196 .height(100) 197 Button('click +3') 198 .onClick(() => { 199 console.info('+3 clicked!') 200 }) 201 } 202 } 203 ```