HarmonyOS实战开发-深度探索与打造个性化自定义组件 - HarmonyOS技术社区 - 电子技术论坛 - 广受欢迎的专业电子论坛
分享 收藏 返回

[文章]

HarmonyOS实战开发-深度探索与打造个性化自定义组件

今天分享一下 什么是自定义组件?及其自定义组件的实战。

做过前端或者android开发的都知道自定义组件,鸿蒙中显示在界面上的UI都称为组件,小打一个按钮,再到一个列表。

鸿蒙提供的组件有 基础组件,容器组件,媒体组件,绘制组件,画布组件组件等,如Button、Text 是基础组件。

由开发者在基础组件基础上 添加一些封装和修饰 定义的组件称为自定义组件。自定义组件的实现大大提高代码的可复用性和可维护性,提高代码效率。

自定义组件:是由@Component装饰的UI单元,可以组合多个系统组件实现UI的复用,可以调用组件的生命周期。

自定义组件和页面的关系

1.自定义组件:@Component装饰的UI单元,可以组合多个系统组件实现UI的复用,可以调用组件的生命周期。

2.页面:即应用的UI页面。可以由一个或者多个自定义组件组成,@Entry装饰的自定义组件为页面的入口组件,即页面的根节点,一个页面有且仅能有一个@Entry。只有被@Entry装饰的组件才可以调用页面的生命周期。

自定义组件的创建和渲染流程

自定义组件的创建:自定义组件的实例由ArkUI框架创建。

初始化自定义组件的成员变量:通过本地默认值或者构造方法传递参数来初始化自定义组件的成员变量,初始化顺序为成员变量的定义顺序。

如果开发者定义了aboutToAppear,则执行aboutToAppear方法。

在首次渲染的时候,执行build方法渲染系统组件,如果子组件为自定义组件,则创建自定义组件的实例。在执行build()函数的过程中,框架会观察每个状态变量的读取状态,将保存两个map:

状态变量 -> UI组件(包括ForEach和if)。

UI组件 -> 此组件的更新函数,即一个lambda方法,作为build()函数的子集,创建对应的UI组件并执行其属性方法,示意如下。

build() {
...
this.observeComponentCreation(() => {
Button.create();
})
this.observeComponentCreation(() => {
Text.create();
})
...
}

上面了解了自定义组件的概念,或许很多不知道怎么去使用自定义组件,下面就用商城项目中的 我的列表来实现:

先通过最简单的方式来实现,每一个里面是竖直布局,并且是由一个图片和一个文本组成:

Column(){
    Image($r('app.media.app_icon')).width(28).height(28)
    Text('互动有礼').fontSize(15)
      .fontColor(Color.Black).margin({ top: 5 })
  }

这样就可以实现每一个功能块。

如果想要实现水平的几个模块功能,需要重复的代码复制几次来实现:

build() {
    Row() {
      Flex({justifyContent: FlexAlign.SpaceAround}){
        Column(){
          Image($r('app.media.app_icon')).width(28).height(28)
          Text('黄金会员').fontSize(15)
            .fontColor(Color.Black).margin({ top: 5 })
        }


        Column(){
          Image($r('app.media.app_icon')).width(28).height(28)
          Text('积分商城').fontSize(15)
            .fontColor(Color.Black).margin({ top: 5 })
        }


        Column(){
          Image($r('app.media.app_icon')).width(28).height(28)
          Text('互动有礼').fontSize(15)
            .fontColor(Color.Black).margin({ top: 5 })
        }


        Column(){
          Image($r('app.media.app_icon')).width(28).height(28)
          Text('红包卡卷').fontSize(15)
            .fontColor(Color.Black).margin({ top: 5 })
        }
      }
      .backgroundColor('#FFFFFF')
      .borderRadius(20)
      .padding(15)
      .margin(10)
    }
    .width('100%')
    .height('100%')
    .backgroundColor('#e1e1e1')
  }

为了实现上面的功能,同样的代码重复写了四遍,虽然看起来简单,只是复制修改一点文本就行,但是这样你代码要冗余很多,还能影响性能和效率。

而且可维护性更差。

这种也算是一种问题,很多公司都要求优化代码,优化的就是这种冗余,影响效率的功能代码。

解决这种优化得最好方式 就是自定义组件:

@Component
struct ConponentDev{
  @State title:string = ''


  build(){
    Flex({justifyContent: FlexAlign.SpaceAround}){
      Column(){
        Image($r('app.media.app_icon')).width(28).height(28)
        Text(this.title).fontSize(15)
          .fontColor(Color.Black).margin({ top: 5 })
      }
    }
    .padding(10)
    .layoutWeight(1)
    .backgroundColor('#FFFFFF')
  }
}

上面代码实现一个竖直布局,里面有一个图片一个文本。

代码定义了一个名为ConponentDev的组件,组件都使用@Component修饰,@Entry表示入口组件,一个文件中可以有多个@Component,而@Entry只能有一个。

我们在入口组件中调用自定义组件ConponentDev:

build() {
    Row(){
      ForEach(this.arrayCon,(content: string)=>{
        ConponentDev({title:content})
      })
    }
    .width('100%')
    .height('100%')
    .padding(10)
    .borderRadius(20)
    .backgroundColor('#e1e1e1')
  }

调用的时候可以使用 :

ForEach(this.arrayCon,(content: string)=>{
  ConponentDev({title:content})
})

这种方式需要定义一个array数组:

@State arrayCon: string[] = ['黄金会员','积分商城','互动有礼','红包卡卷']

也可以使用重复添加多个 ConponentDev({title:content})

Row(){
      ConponentDev({title:content1})
      ConponentDev({title:content2})
      ConponentDev({title:content3})
      ConponentDev({title:content4})
    }
    .width('100%')
    .height('100%')
    .padding(10)
    .borderRadius(20)
    .backgroundColor('#e1e1e1')

最后

如果大家觉得这篇内容对学习鸿蒙开发有帮助,我想邀请大家帮我三个小忙:
点赞,转发,有你们的 『点赞和评论』,才是我创造的动力。
关注小编,同时可以期待后续文章ing?,不定期分享原创知识。
更多鸿蒙最新技术知识点,请关注作者博客:鸿蒙实战经验分享:鸿蒙基础入门开发宝典! (qq.com)

更多回帖

×
发帖