缠丝猫 发表于 2025-1-20 09:06:49

鸿蒙进阶篇-自定义组件

大家好,我是鸿蒙开天组,今天咱们来学习自定义组件。
一、自定义组件定义

在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);
    }
}
}
点击前后的结果分别如下:
https://i-blog.csdnimg.cn/direct/5918c487e41442d194506f913bed98f0.png
https://i-blog.csdnimg.cn/direct/e2be5ac55ede409c8ba8fe5d57a926ad.png
 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企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: 鸿蒙进阶篇-自定义组件