【HarmonyOS Next之旅】ArkTS语法(二) -> 动态构建UI元素

简介: 当开发者创建自定义组件,并想对该组件添加特定功能时(例如在自定义组件中添加一个点击跳转操作)。为解决此问题,引入了@BuilderParam装饰器,此装饰器修饰的属性值可为@Builder装饰的函数,开发者可在初始化自定义组件时对此属性进行赋值,为自定义组件增加特定的功能。@BuilderParam装饰器用于修饰自定义组件内函数类型的属性(例如:@BuilderParam noParam: () => void),并且在初始化自定义组件时被@BuilderParam修饰的属性必须赋值。


目录

1 -> @Builder

2 -> @BuilderParam8+

3 -> @Styles

4 -> @Extend

5 -> @CustomDialog

1 -> @Builder
可通过@Builder装饰器进行描述,该装饰器可以修饰一个函数,此函数可以在build函数之外声明,并在build函数中或其他@Builder修饰的函数中使用,从而实现在一个自定义组件内快速生成多个布局内容。

// Test_Builder.ets
@Component
struct CompB {
@State CompValue: string = ''

aboutToAppear() {
console.info('CompB aboutToAppear.')
}

aboutToDisappear() {
console.info('CompB aboutToDisappear.')
}

build() {
Column() {
Button(this.CompValue)
.margin(5)
}
}
}

@Entry
@Component
struct CompA {
size1: number = 100
@State CompValue1: string = "Hello,CompValue1"
@State CompValue2: string = "Hello,CompValue2"
@State CompValue3: string = "Hello,CompValue3"

// @Builder装饰的函数CompC内使用自定义组件CompB
@Builder CompC(value: string) {
CompB({ CompValue: value })
}

@Builder SquareText(label: string) {
Text(label)
.fontSize(18)
.width(1 this.size1)
.height(1
this.size1)
}

// @Builder装饰的函数RowOfSquareTexts内使用@Builder装饰的函数SquareText
@Builder RowOfSquareTexts(label1: string, label2: string) {
Row() {
this.SquareText(label1)
this.SquareText(label2)
}
.width(2 this.size1)
.height(1
this.size1)
}

build() {
Column() {
Row() {
this.SquareText("A")
this.SquareText("B")
}
.width(2 this.size1)
.height(1
this.size1)

  this.RowOfSquareTexts("C", "D")
  Column() {
    // 使用三次@Builder装饰的自定义组件
    this.CompC(this.CompValue1)
    this.CompC(this.CompValue2)
    this.CompC(this.CompValue3)
  }
  .width(2 * this.size1)
  .height(2 * this.size1)
}
.width(2 * this.size1)
.height(2 * this.size1)
AI 代码解读

}
}

2 -> @BuilderParam8+
@BuilderParam装饰器用于修饰自定义组件内函数类型的属性(例如:@BuilderParam noParam: () => void),并且在初始化自定义组件时被@BuilderParam修饰的属性必须赋值。

2.1 -> 引入动机
当开发者创建自定义组件,并想对该组件添加特定功能时(例如在自定义组件中添加一个点击跳转操作)。若直接在组件内嵌入事件方法,将会导致所有引入该自定义组件的地方均增加了该功能。为解决此问题,引入了@BuilderParam装饰器,此装饰器修饰的属性值可为@Builder装饰的函数,开发者可在初始化自定义组件时对此属性进行赋值,为自定义组件增加特定的功能。

2.2 -> 参数初始化组件
通过参数初始化组件时,将@Builder装饰的函数赋值给@BuilderParam修饰的属性,并在自定义组件内调用该属性值。若@BuilderParam修饰的属性在进行赋值时不带参数(如:noParam: this.specificNoParam),则此属性的类型需定义为无返回值的函数(如:@BuilderParam noParam: () => void);若带参数(如:withParam: this.SpecificWithParam('WithParamA')),则此属性的类型需定义成any(如:@BuilderParam withParam: any)。

// Test_BuilderParam8+.ets
@Component
struct CustomContainer {
header: string = ''
@BuilderParam noParam: () => void
@BuilderParam withParam: any
footer: string = ''

build() {
Column() {
Text(this.header)
.fontSize(30)
this.noParam()
this.withParam()
Text(this.footer)
.fontSize(30)
}
}
}

@Entry
@Component
struct CustomContainerUser {
@Builder specificNoParam() {
Column() {
Text('noParam').fontSize(30)
}
}

@Builder SpecificWithParam(label: string) {
Column() {
Text(label).fontSize(30)
}
}

build() {
Column() {
CustomContainer({
header: 'HeaderA',
noParam: this.specificNoParam,
withParam: this.SpecificWithParam('WithParamA'),
footer: 'FooterA'
})
Divider()
.strokeWidth(3)
.margin(10)
CustomContainer({
header: 'HeaderB',
noParam: this.specificNoParam,
withParam: this.SpecificWithParam('WithParamB'),
footer: 'FooterB'
})
}
}
}

2.3 -> 尾随闭包初始化组件
在自定义组件中使用@BuilderParam修饰的属性时也可通过尾随闭包进行初始化(在初始化自定义组件时,组件后紧跟一个大括号“{}”形成尾随闭包场景(CustomContainer(){})。开发者可把尾随闭包看做一个容器,向其中填充内容,如在闭包内增加组件({Column(){...}),闭包内语法规范与build函数一致。此场景下自定义组件内有且仅有一个使用@BuilderParam修饰的属性。

示例:在闭包内添加Column组件并设置点击事件,在Column组件内调用@Builder修饰的specificParam函数,点击Column组件后将自定义组件CustomContainer中header的属性值由“header”改变为“changeHeader”。在初始化自定义组件CustomContainer时,尾随闭包的内容会被赋值给@BuilderParam修饰的closer属性。

// Test_BuilderParam8+.ets
@Component
struct CustomContainer {
header: string = ''
@BuilderParam closer: () => void

build() {
Column() {
Text(this.header)
.fontSize(30)
this.closer()
}
}
}

@Builder function specificParam(label1: string, label2: string) {
Column() {
Text(label1)
.fontSize(30)
Text(label2)
.fontSize(30)
}
}

@Entry
@Component
struct CustomContainerUser {
@State text: string = 'header'

build() {
Column() {
CustomContainer({
header: this.text,
}) {
Column() {
specificParam('testA', 'testB')
}.backgroundColor(Color.Yellow)
.onClick(() => {
this.text = 'changeHeader'
})
}
}
}
}

3 -> @Styles
ArkTS为了避免开发者对重复样式的设置,通过@Styles装饰器可以将多个样式设置提炼成一个方法,直接在组件声明时调用,通过@Styles装饰器可以快速定义并复用自定义样式。当前@Styles仅支持通用属性。

@Styles可以定义在组件内或组件外,在组件外定义时需在方法名前面添加function关键字,组件内定义时则不需要添加function关键字。

// Test_Styles.ets
@Styles function globalFancy () {
.width(150)
.height(100)
.backgroundColor(Color.Pink)
}

@Entry
@Component
struct FancyUse {
@Styles componentFancy() {
.width(100)
.height(200)
.backgroundColor(Color.Yellow)
}

build() {
Column({ space: 10 }) {
Text('FancyA')
.globalFancy()
.fontSize(30)
Text('FancyB')
.globalFancy()
.fontSize(20)
Text('FancyC')
.componentFancy()
.fontSize(30)
Text('FancyD')
.componentFancy()
.fontSize(20)
}
}
}

@Styles还可以在StateStyles属性内部使用,在组件处于不同的状态时赋予相应的属性。

在StateStyles内可以直接调用组件外定义的@Styles方法,但需要通过this关键字调用组件内定义的@Styles方法。

// Test_Styles.ets
@Styles function globalFancy () {
.width(120)
.height(120)
.backgroundColor(Color.Green)
}

@Entry
@Component
struct FancyUse {
@Styles componentFancy() {
.width(80)
.height(80)
.backgroundColor(Color.Red)
}

build() {
Row({ space: 10 }) {
Button('Fancy')
.stateStyles({
normal: {
.width(100)
.height(100)
.backgroundColor(Color.Blue)
},
disabled: this.componentFancy,
pressed: globalFancy
})
}
}
}
4 -> @Extend
@Extend装饰器将新的属性方法添加到Text、Column、Button等内置组件上,通过@Extend装饰器可以快速地扩展原生组件。

// Test_Extend.ets
@Extend(Text) function fancy (fontSize: number) {
.fontColor(Color.Red)
.fontSize(fontSize)
.fontStyle(FontStyle.Italic)
.fontWeight(600)
}

@Entry
@Component
struct FancyUse {
build() {
Row({ space: 10 }) {
Text("Fancy")
.fancy(16)
Text("Fancy")
.fancy(24)
Text("Fancy")
.fancy(32)
}
}
}
说明

@Extend装饰器不能定义在自定义组件struct内。
@Extend装饰器内仅支持属性方法设置。

5 -> @CustomDialog
@CustomDialog装饰器用于装饰自定义弹窗组件,使得弹窗可以动态设置内容及样式。

// Test_CustomDialog.ets
@CustomDialog
struct DialogExample {
controller: CustomDialogController
action: () => void

build() {
Row() {
Button('Close CustomDialog')
.onClick(() => {
this.controller.close()
this.action()
})
}.padding(20)
}
}

@Entry
@Component
struct CustomDialogUser {
dialogController: CustomDialogController = new CustomDialogController({
builder: DialogExample({ action: this.onAccept }),
cancel: this.existApp,
autoCancel: true
});

onAccept() {
console.info('onAccept');
}

existApp() {
console.info('Cancel dialog!');
}

build() {
Column() {
Button('Click to open Dialog')
.onClick(() => {
this.dialogController.open()
})
}
}
}

感谢各位大佬支持!!!

互三啦!!!

目录
打赏
0
10
11
0
107
分享
相关文章
|
17天前
|
跟老卫学HarmonyOS开发:ArkTS关系型数据库开发
本节以“账本”为例,使用关系型数据库接口实现账单的增、删、改、查操作。通过创建ArkTSRdb应用,演示如何操作RdbStore进行数据管理,并结合界面按钮实现交互功能。
60 0
跟老卫学HarmonyOS开发:ArkTS关系型数据库开发
纯血鸿蒙NEXT即时通讯/IM系统:RinbowTalk正式发布,全源码、纯ArkTS编写
RainbowTalk是一套基于MobileIMSDK的产品级鸿蒙NEXT端IM系统,目前已正式发布。纯ArkTS、从零编写,无套壳、没走捷径,每一行代码都够“纯”(详见:《RainbowTalk详细介绍》)。 MobileIMSDK是一整套开源IM即时通讯框架,历经10年,超轻量级、高度提炼,一套API优雅支持 UDP 、TCP 、WebSocket 三种协议,支持 iOS、Android、H5、标准Java、小程序、Uniapp、鸿蒙NEXT,服务端基于Netty编写。
78 1
详解HarmonyOS NEXT系统中ArkTS和仓颉的混合开发
本文介绍了鸿蒙系统中ArkTs与仓颉语言的混合开发方法,讲解了如何通过DevEco Studio创建混合项目、目录结构特点及组件调用方式,强调编译器自动化处理大幅简化开发流程,提升了开发体验。
【HarmonyOS Next之旅】基于ArkTS开发(三) -> 兼容JS的类Web开发(三)
本文主要介绍了应用开发中的三大核心内容:生命周期管理、资源限定与访问以及多语言支持。在生命周期部分,详细说明了应用和页面的生命周期函数及其触发时机,帮助开发者更好地掌控应用状态变化。资源限定与访问章节,则聚焦于资源限定词的定义、命名规则及匹配逻辑,并阐述了如何通过 `rJSJSON使t` 和 `$tc` 方法实现简单格式化与单复数格式化,为全球化应用提供便利。
162 104
【HarmonyOS Next之旅】基于ArkTS开发(三) -> 兼容JS的类Web开发(二)
本文介绍了HarmonyOS应用开发中的HML、CSS和JS语法。HML作为标记语言,支持数据绑定、事件处理、列表渲染等功能;CSS用于样式定义,涵盖尺寸单位、样式导入、选择器及伪类等特性;JS实现业务逻辑,包括ES6语法支持、对象属性、数据方法及事件处理。通过具体代码示例,详细解析了页面构建与交互的实现方式,为开发者提供全面的技术指导。
184 104
【HarmonyOS Next之旅】基于ArkTS开发(三) -> 兼容JS的类Web开发(一)
该文档详细介绍了一个兼容JS的类Web开发范式的方舟开发框架,涵盖概述、文件组织、js标签配置及app.js等内容。框架采用HML、CSS、JavaScript三段式开发方式,支持单向数据绑定,适合中小型应用开发。文件组织部分说明了目录结构、访问规则和媒体文件格式;js标签配置包括实例名称、页面路由和窗口样式信息;app.js则描述了应用生命周期与对象管理。整体内容旨在帮助开发者快速构建基于方舟框架的应用程序。
173 102
【HarmonyOS Next之旅】基于ArkTS开发(二) -> UI开发四
本文介绍了Web组件开发与性能优化的相关内容。在Web组件开发部分,涵盖创建组件、设置样式与属性、添加事件和方法以及场景示例,如动态播放视频。性能提升方面,推荐使用数据懒加载、条件渲染替代显隐控制、Column/Row替代Flex、设置List组件宽高及调整cachedCount减少滑动白块等方法,以优化应用性能与用户体验。
138 56
【HarmonyOS 5】鸿蒙组件&模板服务详解 - 助力高效开发的利器
在移动应用开发领域,效率与质量始终是开发者追求的核心目标。鸿蒙系统作为新兴的操作系统,为开发者提供了丰富且强大的开发资源,其中鸿蒙组件&模板服务更是成为开发者快速构建高质量应用的得力助手。
91 0
HarmonyOS NEXT仓颉开发语言实战案例:外卖App
仓颉语言实战分享,教你如何用仓颉开发外卖App界面。内容包括页面布局、导航栏自定义、搜索框实现、列表模块构建等,附完整代码示例。轻松掌握Scroll、List等组件使用技巧,提升HarmonyOS应用开发能力。
HarmonyOS NEXT仓颉开发语言实战案例:健身App
本期分享一个健身App首页的布局实现,顶部采用Stack容器实现重叠背景与偏移效果,列表部分使用List结合Scroll实现可滚动内容。代码结构清晰,适合学习HarmonyOS布局技巧。
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等