构建第一个ArkTS之创建自定义组件

在ArkUI中,UI显示的内容均为组件,由框架直接提供的称为系统组件,由开发者定义的称为自定义组件。在进行 UI 界面开发时,通常不是简单的将系统组件进行组合使用,而是需要考虑代码可复用性、业务逻辑与UI分离,后续版本演进等因素。因此,将UI和部分业务逻辑封装成自定义组件是不可或缺的能力。

自定义组件具有以下特点:

  • 可组合:允许开发者组合使用系统组件、及其属性和方法。
  • 可重用:自定义组件可以被其他组件重用,并作为不同的实例在不同的父组件或容器中使用。
  • 数据驱动UI更新:通过状态变量的改变,来驱动UI的刷新。

自定义组件的基本用法

以下示例展示了自定义组件的基本用法。

@Component
struct HelloComponent {@State message: string = 'Hello, World!';build() {// HelloComponent自定义组件组合系统组件Row和TextRow() {Text(this.message).onClick(() => {// 状态变量message的改变驱动UI刷新,UI从'Hello, World!'刷新为'Hello, ArkUI!'this.message = 'Hello, ArkUI!';})}}
}


说明
如果在另外的文件中引用该自定义组件,需要使用export关键字导出,并在使用的页面import该自定义组件。

HelloComponent可以在其他自定义组件中的build()函数中多次创建,实现自定义组件的重用。

@Entry
@Component
struct ParentComponent {build() {Column() {Text('ArkUI message')HelloComponent({ message: 'Hello, World!' });Divider()HelloComponent({ message: '你好!' });}}
}


要完全理解上面的示例,需要了解自定义组件的以下概念定义,本文将在后面的小节中介绍:

自定义组件的基本结构
成员函数/变量
自定义组件的参数规定
build()函数
自定义组件通用样式

自定义组件的基本结构

  • struct:自定义组件基于struct实现,struct + 自定义组件名 + {...}的组合构成自定义组件,不能有继承关系。对于struct的实例化,可以省略new。

    说明

    自定义组件名、类名、函数名不能和系统组件名相同。

  • @Component:@Component装饰器仅能装饰struct关键字声明的数据结构。struct被@Component装饰后具备组件化的能力,需要实现build方法描述UI,一个struct只能被一个@Component装饰。

    说明

    从API version 9开始,该装饰器支持在ArkTS卡片中使用。

@Component
struct MyComponent {
}


build()函数:build()函数用于定义自定义组件的声明式UI描述,自定义组件必须定义build()函数。

@Component
struct MyComponent {build() {}
}


@Entry:@Entry装饰的自定义组件将作为UI页面的入口。在单个UI页面中,最多可以使用@Entry装饰一个自定义组件。@Entry可以接受一个可选的LocalStorage的参数。
说明
从API version 9开始,该装饰器支持在ArkTS卡片中使用。

@Entry
@Component
struct MyComponent {
}

成员函数/变量

自定义组件除了必须要实现build()函数外,还可以实现其他成员函数,成员函数具有以下约束:

  • 自定义组件的成员函数为私有的,且不建议声明成静态函数

自定义组件可以包含成员变量,成员变量具有以下约束:

  • 自定义组件的成员变量为私有的,且不建议声明成静态变量。
  • 自定义组件的成员变量本地初始化有些是可选的,有些是必选的。具体是否需要本地初始化,是否需要从父组件通过参数传递初始化子组件的成员变量,请参考状态管理。

自定义组件的参数规定

从上文的示例中,我们已经了解到,可以在build方法里创建自定义组件,在创建自定义组件的过程中,根据装饰器的规则来初始化自定义组件的参数。

@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.someColorMyComponent({ countDownFrom: 10, color: this.someColor })}}
}

build()函数

所有声明在build()函数的语言,我们统称为UI描述,UI描述需要遵循以下规则:

  • @Entry装饰的自定义组件,其build()函数下的根节点唯一且必要,且必须为容器组件,其中ForEach禁止作为根节点。

    @Component装饰的自定义组件,其build()函数下的根节点唯一且必要,可以为非容器组件,其中ForEach禁止作为根节点。

@Entry
@Component
struct MyComponent {build() {// 根节点唯一且必要,必须为容器组件Row() {ChildComponent() }}
}@Component
struct ChildComponent {build() {// 根节点唯一且必要,可为非容器组件Image('test.jpg')}
}

不允许声明本地变量,反例如下。

build() {// 反例:不允许声明本地变量let a: number = 1;
}

不允许在UI描述里直接使用console.info,但允许在方法或者函数里使用,反例如下。

build() {// 反例:不允许console.infoconsole.info('print debug log');
}

不允许创建本地的作用域,反例如下。

build() {// 反例:不允许本地作用域{...}
}


不允许调用没有用@Builder装饰的方法,允许系统组件的参数是TS方法的返回值。

@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())}}
}


不允许switch语法,如果需要使用条件判断,请使用if。反例如下。

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所处的开发者不可见的容器组件上。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/805061.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

vue中使用use引入的svg怎么添加title

项目框架: vue2 使用场景: 我们项目中的svg文件比较多,每个都copy里面的svg代码的话,会造成需要写很多个vue文件,于是乎当时采用了use的方式引入了svg文件 代码如下(当然中间省去了其他步骤&#xff0c…

4.19号驱动

1. ARM裸机开发和Linux系统开发的异同 相同点:都是对硬件进行操作 不同点: 有无操作系统 是否具备多进程多线程开发 是否可以调用库函数 操作地址是否相同,arm操作物理地址,驱动操作虚拟地址 2. Linux操作系统的层次 应用层…

(2022级)成都工业学院数据库原理及应用实验二:CASE工具关系模型建模

写在前面 1、基于2022级软件工程/计算机科学与技术实验指导书 2、代码仅提供参考 3、如果代码不满足你的要求,请寻求其他的途径 运行环境 window11家庭版 PowerDesigner 16.1 实验要求 某医院一个门诊部排班管理子系统涉及如下信息: 若干科室&a…

Echarts+vue-baidu-map绘制行驶路线

依赖下载 首先要在Vue项目中结合vue-baidu-map和ECharts绘制行驶路线,需要先安装并导入相关的库 npm install vue-baidu-map echarts --save注册引入 Echarts引入详情 官网查看 import * as echarts from echarts;// 基于准备好的dom,初始化echarts实…

成都百洲文化传媒有限公司靠谱吗?怎么样?

随着互联网的迅猛发展,电子商务行业迎来了前所未有的发展机遇。在这个变革的浪潮中,成都百洲文化传媒有限公司凭借其深厚的行业经验和创新的服务模式,正逐渐成为电商服务领域的新领军者。 一、创新引领,塑造电商服务新标准 成都百…

VS选择数据源数据提供程序的区别

VS选择数据源数据提供程序的区别 1、用于OLE DB的.net framework 数据提供程序 OLE DB是微软提供的一种数据访问技术,它允许应用程序访问存储在不同类型的数据源中的数据。.NET Framework 提供了一个用于OLE DB的数据提供程序,允许开发人员使用ADO.NET…

Windows下docker-compose部署DolphinScheduler

参照:快速上手 - Docker部署(Docker) - 《Apache DolphinScheduler v3.1.0 使用手册》 - 书栈网 BookStack 下载源文件 地址:https://dolphinscheduler.apache.org/zh-cn/download/3.2.1 解压到指定目录,进入apache-dolphinscheduler-xxx-…

蓝桥杯备考随手记: 递归

递归是一种解决问题的方法,通过将原问题分解为更小的、相同形式的子问题来解决。在递归中,函数会调用自身来解决这些子问题,直到达到基本情况(终止条件),然后逐层返回结果,最终得到整个问题的解…

vscode开发小程序项目并在微信开发者工具运行

需求:vscode开发uniapp之后在微信开发者工具运行,更改的时候微信开发者也同步更改 创建微信小程序所需插件,在vscode的插件管理里面安装就可以了 1.微信小程序开发工具 2.vscode weapp api 3.vscode wxml 4.vscode wechat 1.创建小程序命…

vue3的 watch

两个例子中,主要区别在于监视的对象不同 watch( tablelist.value, () > { console.log(tablelist.value, "tablelist"); }, { deep: true }, ); watch 监视的是 tablelist.value 的值。也就是说,当 tablelist.value 发生变化时&#xff0c…

[HDCTF 2023]Normal_Rsa(revenge)(素数分解)

题目:(注释为分析) from Crypto.Util.number import * #from shin import flagmbytes_to_long(bHDCTF{******}) e65537 pgetPrime(256) qgetPrime(512) rgetPrime(512) np*q*r## phi(p-1)*(q-1)*(r-1) Ppow(p,2,n)## Pp**2 piroof(P,2) Qpo…

前端md5校验文件

前端获取文件的md5值,与文件一同传到后端,后端同样对md5值进行校验。如果相同,则文件未被损坏(其实这种方式优点类似于tcp、ip的差错校验,好像token也是这种方式) 项目准备 前端并不可能手写一个算法来实…

python新特性

字符串格式化输出 字符串格式化输出 formatted字符串是带有f字符前缀的字符串,可以很方便的格式化字符串 #旧版本 name 泉信 print(公司是: %s%name) print(公司是: {}.format(name)) #新版本 print(f欢迎加入: {name}) lang…

c++学生排名表(析构函数)

现在输入一批学生(人数大于0且不超过100)的名次和他们的姓名。要求按名次输出每个人的排名。 输入格式:每行为一个学生的信息,共两项,第一项为排名(为正整数,且任意两名学生的排名均不同&#…

2024年武汉中级工程师评审学历、论文、业绩有什么要求?

2024年大部分地区职称申报已经开始,今年因为政策变动,基本上需要全员参加水平能力测试,水测通过之后安排评审,那么对于中级职称评审有什么要求呢?我们一起跟甘建二看看。 一、2024年武汉中级工程师职称评审学历要求&am…

Web前端—属性描述符

属性描述符 假设有一个对象obj var obj {a:1 }观察这个对象,我们如何来描述属性a: 值为1可以重写可以遍历 我们可以通过Object.getOwnPropertyDescriptor得到它的属性描述符 var desc Object.getOwnPropertyDescriptor(obj, a); console.log(desc);我…

安卓逆向 | 某X游戏垂类Web nonce

*本案例仅做分析参考,如有侵权请联系删除 1.逻辑分析 通过XHR断点,然后逐步往上调发现nonce生出处。 在console执行下函数 其中 i,是当前日期和时间的秒级时间戳,并将其向下取整到最接近的整数。 i = ~~(+_.w() / 1e3)w</

设计模式之迭代器模式(上)

迭代器模式 1&#xff09;概述 1.概念 存储多个成员对象&#xff08;元素&#xff09;的类叫聚合类(Aggregate Classes)&#xff0c;对应的对象称为聚合对象。 聚合对象有两个职责&#xff0c;一是存储数据&#xff0c;二是遍历数据。 2.概述 迭代器模式(Iterator Patter…

Go语言不能常量取址!?

题如下图 在软件开发中&#xff0c;常量是一种重要的编程元素&#xff0c;它们在程序中起到固定值的作用被大量使用 Go语言中的常量取址 在 Go 语言中&#xff0c;常量是无法被取址的。这意味着我们不能使用取址操作符 & 来获取常量的地址。例如&#xff1a; const a …