赞
踩
1:组件必须使用
@Component
装饰
2:@Entry
装饰在哪个组件上,页面就展示哪个组件(主组件)
3:被@Entry
装饰的主组件,build()
中必须有且仅有一个根容器组件,其它自定义组件,build()
中有且仅有一个根组件。
在ArkUI中,UI显示的内容均为组件,由框架直接提供的称为系统组件,由开发者定义的称为自定义组件。在进行 UI 界面开发时,通常不是简单的将系统组件进行组合使用,而是需要考虑代码可复用性、业务逻辑与UI分离,后续版本演进等因素。因此,将UI和部分业务逻辑封装成自定义组件是不可或缺的能力。
一个项目下所有的自定义的组件名不可以重复,无论是否在一个ets文件中
自定义组件具有以下特点:
//src/main/ets/pages/CustomComponents.ets // 创建自定义组件 @Component struct itemComponent { // 自定义组件可以使用变量(都是私有化的) 传递参数 content: string = '青山隐隐水迢迢,秋尽江南草未凋。' // 哪种情况可以驱动UI更新。@state @State isDone: boolean = false build() { // 必须有一个根组件。 Row() { Image(this.isDone ? $r('app.media.todo_ok') : $r('app.media.todo_default')) .width(20) .height(20) .margin(15) Text(this.content) .decoration({ type: this.isDone ? TextDecorationType.LineThrough : TextDecorationType.None }) } .backgroundColor(Color.Pink) .borderRadius(25) .margin({ top: 15 }) .onClick(() => { this.isDone = !this.isDone }) } }
itemComponent
可以在其他自定义组件中的build()
函数中多次创建,实现自定义组件的重用。@Entry @Component struct CustomComponents { @State message: string = '诗词学习' build() { Row() { Column() { Text(this.message) .fontSize(50) .fontWeight(FontWeight.Bold) itemComponent() itemComponent({ content: '二十四桥明月夜,玉人何处教吹箫?' }) itemComponent({ content: '荷尽已无擎雨盖,菊残犹有傲霜枝。' }) itemComponent({ content: '一年好景君须记,最是橙黄橘绿时。' }) } .width('100%') } .height('100%') } }
要完全理解上面的示例,需要了解自定义组件的以下概念定义,本文将在后面的小节中介绍:
struct
+ 自定义
组件名 + {...}
的组合构成自定义组件,不能有继承关系。对于struct的实例化,可以省略new。说明:自定义组件名、类名、函数名不能和系统组件名相同。
说明:从API version 9开始,该装饰器支持在ArkTS卡片中使用。
@Component
struct MyComponent {
}
@Component
struct MyComponent {
build() {
}
}
说明:从API version 9开始,该装饰器支持在ArkTS卡片中使用。
@Entry
@Component
struct MyComponent {
}
自定义组件除了必须要实现build()
函数外,还可以实现其他成员函数,成员函数具有以下约束:
自定义组件可以包含成员变量,成员变量具有以下约束:
从上文的示例中,我们已经了解到,可以在build方法或者@Builder装饰的函数里创建自定义组件,在创建自定义组件的过程中,根据装饰器的规则来初始化自定义组件的参数。
@Component struct MyComponent { private countDownFrom: number = 0; private color: Color = Color.Blue; build() { } } @Entry @Component struct ParentComponent { private someColor: Color = Color.Pink; build() { Column() { // 创建MyComponent实例,并将创建MyComponent成员变量countDownFrom初始化为10,将成员变量color初始化为this.someColor MyComponent({ countDownFrom: 10, color: this.someColor }) } } }
所有声明在build()
函数的语言,我们统称为UI描述,UI描述需要遵循以下规则:
@Component装饰的自定义组件,其build()函数下的根节点唯一且必要,可以为非容 器组件,其中ForEach禁止作为根节点。
@Entry @Component struct MyComponent { build() { // 根节点唯一且必要,必须为容器组件 Row() { ChildComponent() } } } @Component struct ChildComponent { build() { // 根节点唯一且必要,可为非容器组件 Image('test.jpg') } }
build() {
// 反例:不允许声明本地变量
let a: number = 1;
}
build() {
// 反例:不允许console.info
console.info('print debug log');
}
build() {
// 反例:不允许本地作用域
{
...
}
}
@Component struct ParentComponent { doSomeCalculations() { } calcTextValue(): string { return 'Hello World'; } @Builder doSomeRender() { Text(Hello World) } build() { Column() { // 反例:不能调用没有用@Builder装饰的方法 this.doSomeCalculations(); // 正例:可以调用 this.doSomeRender(); // 正例:参数可以为调用TS方法的返回值 Text(this.calcTextValue()) } } }
build() { Column() { // 反例:不允许使用switch语法 switch (expression) { case 1: Text('...') break; case 2: Image('...') break; default: Text('...') break; } } }
build() {
Column() {
// 反例:不允许使用表达式
(this.aVar > 10) ? Text('...') : Image('...')
}
}
自定义组件通过“.
”链式调用的形式设置通用样式。
@Component struct MyComponent2 { build() { Button(Hello World) } } @Entry @Component struct MyComponent { build() { Row() { MyComponent2() .width(200) .height(300) .backgroundColor(Color.Red) } } }
说明
ArkUI给自定义组件设置样式时,相当于给MyComponent2套了一个不可见的容器组件,而这些样式是设置在容器组件上的,而非直接设置给MyComponent2的Button组件。通过渲染结果我们可以很清楚的看到,背景颜色红色并没有直接生效在Button上,而是生效在Button所处的开发者不可见的容器组件上。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。