鸿蒙进阶篇-自定义组件

打印 上一主题 下一主题

主题 886|帖子 886|积分 2658

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

在ArkUI中,UI显示的内容均为组件,由框架直接提供的称为系统组件,由开发者定义的称为自定义组件。在进行 UI 界面开发时,通常不是简单的将系统组件进行组合使用,而是必要思量代码可复用性、业务逻辑与UI分离,后续版本演进等因素。因此,将UI和部分业务逻辑封装成自定义组件是不可或缺的能力。
相比于之前学习的轻量级 UI 复用机制 @Builder,自定义组件的功能更为强盛,日常开发中如果要对 【UI 或业务逻辑】进行复用,必要【掌握】自定义组件的能力。
二、自定义组件特点

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


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

1.1自定义组件创建

首先自定义组件必要创建出来,创建的自定义组件根本语法如下:
  1. // 创建
  2. @Component
  3. struct MyComponent {
  4.   // 状态变量
  5.   @State message:string =''
  6.   build(){
  7.     // .... 描述 UI
  8.   }
  9. }
复制代码
观察以上结构,紧张分成三个部分,可以明白成这是自定义组件创建的固定写法:


  • @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页面里了,我们用一个简单的例子来看看自定义组件的根本用法,上代码演示:
  1. @Component
  2. struct HelloComponent {
  3.   @State message: string = 'mate70还没发布';
  4.   build() {
  5.     // HelloComponent自定义组件组合系统组件Row和Text
  6.     Row() {
  7.       Text(this.message)
  8.         .onClick(() => {
  9.           // 状态变量message的改变驱动UI刷新,UI从'mate70还没发布'或'mate70发布了'刷新为'mate70发布啦啊啊啊!'
  10.           this.message = 'mate70发布啦啊啊啊!';
  11.         })
  12.         .width('100%')
  13.         .height(60)
  14.         .fontSize(20)
  15.         .backgroundColor('#E6E6E6')
  16.         .textAlign(TextAlign.Center)
  17.     }
  18.   }
  19. }
  20. /*-----------------------两个组件之间的分割线-------------------------*/
  21. class HelloComponentParam {
  22.   message: string = ""
  23. }
  24. @Entry
  25. @Component
  26. struct ParentComponent {
  27.   param: HelloComponentParam = {
  28.     message: 'mate70发布了'
  29.   }
  30.   build() {
  31.     Column() {
  32.       Text('mate70发布了吗?')
  33.         .fontSize(20)
  34.         .width('100%')
  35.         .height(60)
  36.         .backgroundColor('#E6E6E6')
  37.         .textAlign(TextAlign.Center)
  38.       HelloComponent();
  39.       Divider()
  40.       HelloComponent(this.param);
  41.     }
  42.   }
  43. }
复制代码
点击前后的结果分别如下:


 1.3自定义组件传值

自定义组件除了必须要实现build()函数外,其他【属性】和【方法】的写法跟之前一样,也可以通过点语法设置通用样式,由于都和之前一样,这里就不再说明。
而从上面的例子,我们还可以看出,使用自定义组件时,小括号中没有传值,就会使用自定义组件HelloComponent中定义的message默认值,即“mate70还没发布”;如果在小括号中传同名的值即message时,默认值就会被覆盖,显示为“mate70发布了”。
以上例子上,我们可以把ParentComponent称为父组件,而在它内部调用的HelloComponent称之为子组件,今后这种父组件和子组件之间的参数传递会非常常见。
1.4传递回调参数

使用自定义组件时还有一种传递回调函数的写法,这种写法非常紧张。咱们来看看它的适用场景:

  • 必要父组件传递【逻辑代码】给子组件
  • 在 1 的基础上,子组件必要【传递数据】给父组件
基础代码结构如下:
  1. @Component
  2. struct 子组件 {
  3.   // 1.定义箭头函数
  4.   func1 = () => {}
  5.   func2 = (参数: 类型) => {}
  6.   build() {
  7.     // 略 2.根据情境调用 func1,func2并传递参数
  8.   }
  9. }
  10. @Entry
  11. @Component
  12. struct 父组件 {
  13.   build() {
  14.     子组件({
  15.       // 3. 父组件传递回调函数给子组件
  16.       func1: () => {
  17.         // 具体的逻辑
  18.       },
  19.       func2: (参数: 类型) => {
  20.         // 具体的逻辑
  21.       }
  22.     })
  23.   }
  24. }
复制代码
比如通过定义子组件的箭头函数,实现点击+1到+4的累加结果,这是不传递参数的写法:
  1. @Component
  2. struct addCom {
  3.   // 1. 定义点击+1-+4的箭头函数
  4.   addOne = () => {
  5.   }
  6.   addTwo = () => {
  7.   }
  8.   addThree = () => {
  9.   }
  10.   addFour = () => {
  11.   }
  12.   build() {
  13.     Column() {
  14.       Text('累加器')
  15.         .fontSize(20)
  16.       Row() {
  17.         // 2. 调用+1-+4对应的回调函数
  18.         Button('点击+1')
  19.           .onClick(() => {
  20.             this.addOne()
  21.           })
  22.         Button('点击+2')
  23.           .onClick(() => {
  24.             this.addTwo()
  25.           })
  26.         Button('点击+3')
  27.           .onClick(() => {
  28.             this.addThree()
  29.           })
  30.         Button('点击+4')
  31.           .onClick(() => {
  32.             this.addFour()
  33.           })
  34.       }
  35.       .width('100%')
  36.       .justifyContent(FlexAlign.SpaceBetween)
  37.     }
  38.     .border({ width: 1 })
  39.     .padding(5)
  40.   }
  41. }
  42. @Entry
  43. @Component
  44. struct Page04_callback {
  45.   @State num: number = 0
  46.   build() {
  47.     Column() {
  48.       Text('回调函数')
  49.         .fontSize(50)
  50.         .fontWeight(FontWeight.Bold)
  51.       Text('num:' + this.num)
  52.         .fontSize(30)
  53.       addCom({
  54.         // 3. 传递回调函数
  55.         addOne: () => {
  56.           this.num++
  57.         },
  58.         addTwo: () => {
  59.           this.num += 2
  60.         },
  61.         addThree: () => {
  62.           this.num += 3
  63.         },
  64.         addFour: () => {
  65.           this.num += 4
  66.         }
  67.       })
  68.     }
  69.     .height('100%')
  70.   }
  71. }
复制代码
但如果使用参数传递,可以简化代码誊写,改写结果如下,功能是相同的:
  1. @Component
  2. struct addCom {
  3.   // 点击+1-+4的箭头函数
  4.   addCount = (count: number) => {
  5.   }
  6.   build() {
  7.     Column() {
  8.       Text('累加器-传递参数')
  9.         .fontSize(20)
  10.       Row() {
  11.         Button('点击+1')
  12.           .onClick(() => {
  13.             this.addCount(1)
  14.           })
  15.         Button('点击+2')
  16.           .onClick(() => {
  17.             this.addCount(2)
  18.           })
  19.         Button('点击+3')
  20.           .onClick(() => {
  21.             this.addCount(3)
  22.           })
  23.         Button('点击+4')
  24.           .onClick(() => {
  25.             this.addCount(4)
  26.           })
  27.       }
  28.       .width('100%')
  29.       .justifyContent(FlexAlign.SpaceBetween)
  30.     }
  31.     .border({ width: 1 })
  32.     .padding(5)
  33.   }
  34. }
  35. @Entry
  36. @Component
  37. struct Page04_callback {
  38.   @State num: number = 0
  39.   build() {
  40.     Column() {
  41.       Text('回调函数')
  42.         .fontSize(50)
  43.         .fontWeight(FontWeight.Bold)
  44.       Text('num:' + this.num)
  45.         .fontSize(30)
  46.       addCom({
  47.         addCount: (count: number) => {
  48.           this.num += count
  49.         }
  50.       })
  51.     }
  52.     .height('100%')
  53.   }
  54. }
复制代码
好了,关于自定义组件的分享就到这里,感谢阅读,你的点赞和收藏都是莫大的支持,谢谢!


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

缠丝猫

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表