大家好,我是鸿蒙开天组,今天咱们来学习自定义组件。
一、自定义组件定义
在ArkUI中,UI显示的内容均为组件,由框架直接提供的称为系统组件,由开发者定义的称为自定义组件。在进行 UI 界面开发时,通常不是简单的将系统组件进行组合使用,而是必要思量代码可复用性、业务逻辑与UI分离,后续版本演进等因素。因此,将UI和部分业务逻辑封装成自定义组件是不可或缺的能力。
相比于之前学习的轻量级 UI 复用机制 @Builder,自定义组件的功能更为强盛,日常开发中如果要对 【UI 或业务逻辑】进行复用,必要【掌握】自定义组件的能力。
二、自定义组件特点
自定义组件具有以下特点:
- 可组合:允许开发者组合使用系统组件、及其属性和方法。
- 可重用:自定义组件可以被其他组件重用,并作为差别的实例在差别的父组件或容器中使用。
- 数据驱动UI更新:通过状态变量的改变,来驱动UI的刷新。
三、自定义组件根本用法
1.1自定义组件创建
首先自定义组件必要创建出来,创建的自定义组件根本语法如下:
- // 创建
- @Component
- struct MyComponent {
- // 状态变量
- @State message:string =''
- build(){
- // .... 描述 UI
- }
- }
复制代码 观察以上结构,紧张分成三个部分,可以明白成这是自定义组件创建的固定写法:
- @Component:@Component装饰器仅能装饰struct关键字声明的数据结构。
- struct:自定义组件基于struct实现,struct + 自定义组件名 + {...}的组合构成自定义组件,不能有继承关系。对于struct的实例化,可以省略new。
- build()函数:build()函数用于定义自定义组件的声明式UI描述,自定义组件必须定义build()函数。
要注意的是,struct后面的自定义组件名,这个名称就是自定义组件的标记,不能和系统组件名相同,比如不能命名成Text、Image等
有些细心的同学大概已经注意到,这个结构和咱们平时打开的默认页面结构很像,但是默认页面上,还多出了一个@Entry:
- @Entry:@Entry装饰的自定义组件将作为UI页面的入口。在单个UI页面中,最多可以使用@Entry装饰一个自定义组件。
在我们的单个组件中,没有使用@Entry去装饰的时间,想要单独预览它的结果,也可以思量使用@Preview装饰,再点击预览器即可预览结果。
1.2自定义组件使用
接下来是自定义组件的使用,使用当然是丢进有@Entry装饰的UI页面里了,我们用一个简单的例子来看看自定义组件的根本用法,上代码演示:
- @Component
- struct HelloComponent {
- @State message: string = 'mate70还没发布';
- build() {
- // HelloComponent自定义组件组合系统组件Row和Text
- Row() {
- Text(this.message)
- .onClick(() => {
- // 状态变量message的改变驱动UI刷新,UI从'mate70还没发布'或'mate70发布了'刷新为'mate70发布啦啊啊啊!'
- this.message = 'mate70发布啦啊啊啊!';
- })
- .width('100%')
- .height(60)
- .fontSize(20)
- .backgroundColor('#E6E6E6')
- .textAlign(TextAlign.Center)
- }
- }
- }
- /*-----------------------两个组件之间的分割线-------------------------*/
- class HelloComponentParam {
- message: string = ""
- }
- @Entry
- @Component
- struct ParentComponent {
- param: HelloComponentParam = {
- message: 'mate70发布了'
- }
- build() {
- Column() {
- Text('mate70发布了吗?')
- .fontSize(20)
- .width('100%')
- .height(60)
- .backgroundColor('#E6E6E6')
- .textAlign(TextAlign.Center)
- HelloComponent();
- Divider()
- HelloComponent(this.param);
- }
- }
- }
复制代码 点击前后的结果分别如下:
1.3自定义组件传值
自定义组件除了必须要实现build()函数外,其他【属性】和【方法】的写法跟之前一样,也可以通过点语法设置通用样式,由于都和之前一样,这里就不再说明。
而从上面的例子,我们还可以看出,使用自定义组件时,小括号中没有传值,就会使用自定义组件HelloComponent中定义的message默认值,即“mate70还没发布”;如果在小括号中传同名的值即message时,默认值就会被覆盖,显示为“mate70发布了”。
以上例子上,我们可以把ParentComponent称为父组件,而在它内部调用的HelloComponent称之为子组件,今后这种父组件和子组件之间的参数传递会非常常见。
1.4传递回调参数
使用自定义组件时还有一种传递回调函数的写法,这种写法非常紧张。咱们来看看它的适用场景:
- 必要父组件传递【逻辑代码】给子组件
- 在 1 的基础上,子组件必要【传递数据】给父组件
基础代码结构如下:
- @Component
- struct 子组件 {
- // 1.定义箭头函数
- func1 = () => {}
- func2 = (参数: 类型) => {}
- build() {
- // 略 2.根据情境调用 func1,func2并传递参数
- }
- }
- @Entry
- @Component
- struct 父组件 {
- build() {
- 子组件({
- // 3. 父组件传递回调函数给子组件
- func1: () => {
- // 具体的逻辑
- },
- func2: (参数: 类型) => {
- // 具体的逻辑
- }
- })
- }
- }
复制代码 比如通过定义子组件的箭头函数,实现点击+1到+4的累加结果,这是不传递参数的写法:
- @Component
- struct addCom {
- // 1. 定义点击+1-+4的箭头函数
- addOne = () => {
- }
- addTwo = () => {
- }
- addThree = () => {
- }
- addFour = () => {
- }
- build() {
- Column() {
- Text('累加器')
- .fontSize(20)
- Row() {
- // 2. 调用+1-+4对应的回调函数
- Button('点击+1')
- .onClick(() => {
- this.addOne()
- })
- Button('点击+2')
- .onClick(() => {
- this.addTwo()
- })
- Button('点击+3')
- .onClick(() => {
- this.addThree()
- })
- Button('点击+4')
- .onClick(() => {
- this.addFour()
- })
- }
- .width('100%')
- .justifyContent(FlexAlign.SpaceBetween)
- }
- .border({ width: 1 })
- .padding(5)
- }
- }
- @Entry
- @Component
- struct Page04_callback {
- @State num: number = 0
- build() {
- Column() {
- Text('回调函数')
- .fontSize(50)
- .fontWeight(FontWeight.Bold)
- Text('num:' + this.num)
- .fontSize(30)
- addCom({
- // 3. 传递回调函数
- addOne: () => {
- this.num++
- },
- addTwo: () => {
- this.num += 2
- },
- addThree: () => {
- this.num += 3
- },
- addFour: () => {
- this.num += 4
- }
- })
- }
- .height('100%')
- }
- }
复制代码 但如果使用参数传递,可以简化代码誊写,改写结果如下,功能是相同的:
- @Component
- struct addCom {
- // 点击+1-+4的箭头函数
- addCount = (count: number) => {
- }
- build() {
- Column() {
- Text('累加器-传递参数')
- .fontSize(20)
- Row() {
- Button('点击+1')
- .onClick(() => {
- this.addCount(1)
- })
- Button('点击+2')
- .onClick(() => {
- this.addCount(2)
- })
- Button('点击+3')
- .onClick(() => {
- this.addCount(3)
- })
- Button('点击+4')
- .onClick(() => {
- this.addCount(4)
- })
- }
- .width('100%')
- .justifyContent(FlexAlign.SpaceBetween)
- }
- .border({ width: 1 })
- .padding(5)
- }
- }
- @Entry
- @Component
- struct Page04_callback {
- @State num: number = 0
- build() {
- Column() {
- Text('回调函数')
- .fontSize(50)
- .fontWeight(FontWeight.Bold)
- Text('num:' + this.num)
- .fontSize(30)
- addCom({
- addCount: (count: number) => {
- this.num += count
- }
- })
- }
- .height('100%')
- }
- }
复制代码 好了,关于自定义组件的分享就到这里,感谢阅读,你的点赞和收藏都是莫大的支持,谢谢!
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |