鸿蒙原生应用从设置页看自定义组件的使用

2024-01-11 16:04:58 浏览数 (2)

运行环境

IDE:DevEco Studio 4.0 Release Build Version: 4.0.0.600, built on October 17, 2023

SDK:4.0.10.13

开发板:DAYU200版本4.0.10.16

设置页效果

image-20240107150609169

首先我们用传统的方式去实现,代码如下。

普通方式

代码语言:javascript复制
      Row() {
        Image($r("app.media.hy")).width(50).margin({
          left: 40, right: 20
        })
        Text("会员").fontSize(30).fontWeight(800)
      }.width("100%").backgroundColor(Color.White)

      Row() {
        Image($r("app.media.yx")).width(50).margin({
          left: 40, right: 20
        })
        Text("邮箱").fontSize(30).fontWeight(800)
      }.width("100%").backgroundColor(Color.White)

      Row() {
        Image($r("app.media.cg")).width(50).margin({
          left: 40, right: 20
        })
        Text("草稿").fontSize(30).fontWeight(800)


      }.width("100%").backgroundColor(Color.White)

但大家也都发现了,这里面出来图标和标题不一样,布局是一样的,这样的情况下我们可以考虑用自定义组件去实现

自定义组件的三个特点

自定义组件的特点

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

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

自定义组件的基本结构

  • struct:自定义组件基于struct实现,struct 自定义组件名 {...}的组合构成自定义组件,不能有继承关系。对于struct的实例化,可以省略new。需要说明的是自定义组件名、类名、函数名不能和系统组件名相同。
  • @Component:@Component装饰器仅能装饰struct关键字声明的数据结构。struct被@Component装饰后具备组件化的能力,需要实现build方法描述UI,一个struct只能被一个@Component装饰。@Component可以接受一个可选的bool类型参数。

了解了自定义组件的基本结构以后,我们来实现一下设置页的自定义组件,如下代码所以。

代码语言:javascript复制
@Component
export  struct SettingComponent {
  private  img: Resource = $r("app.media.yx")
  private title: string = ""

  build() {

    Row() {
      Image(this.img).width(50).margin({
        left: 40, right: 20
      })
      Text(this.title).fontSize(30).fontWeight(800)
    }.width("100%").backgroundColor(Color.White)

  }
}

使用办法

第一步导入

代码语言:javascript复制
import { SettingComponent } from '../com/SettingComponent'

第二步使用

代码语言:javascript复制
  SettingComponent({
        title: "会员",
        img: $r("app.media.hy")
      })
      SettingComponent({
        title: "邮箱",
        img: $r("app.media.yx")
      })
      SettingComponent({
        title: "草稿",
        img: $r("app.media.cg")
      })

对比上面的传统方式,自定义组件重用性更高。代码量也可以降低。

我们给自定义组件添加一个点击事件

代码语言:javascript复制
@Component
export struct SettingComponent {
  private img: Resource = $r("app.media.yx")
  private title: string = ""
  private itemOnClick = (event: ClickEvent) => {
  } //item的单击事件(可选)

  build() {

    Row() {
      Image(this.img).width(50).margin({
        left: 40, right: 20
      })
      Text(this.title).fontSize(30).fontWeight(800)
      Blank()
      Image($r("app.media.back")).width(50)
    }.width("100%").backgroundColor(Color.White).margin({
      bottom: 10
    }).onClick((event: ClickEvent) => {
      this.itemOnClick(event)
    })

  }
}

使用

代码语言:javascript复制
  SettingComponent({
        title: "草稿",
        img: $r("app.media.cg"),
        itemOnClick:()=>{
          router.pushUrl({
            url:"pages/Index"
          })
        }
      })

使用之后,我们再来看一下自定义组件的生命周期

自定义组件的生命周期

aboutToAppear

aboutToAppear?(): void

aboutToAppear函数在创建自定义组件的新实例后,在执行其build()函数之前执行。允许在aboutToAppear函数中改变状态变量,更改将在后续执行build()函数中生效。

从API version 9开始,该接口支持在ArkTS卡片中使用。

aboutToDisappear

aboutToDisappear?(): void

aboutToDisappear函数在自定义组件析构销毁之前执行。不允许在aboutToDisappear函数中改变状态变量,特别是@Link变量的修改可能会导致应用程序行为不稳定。

从API version 9开始,该接口支持在ArkTS卡片中使用。

onPageShow

onPageShow?(): void

页面每次显示时触发一次,包括路由过程、应用进入前台等场景,仅@Entry装饰的自定义组件生效。

onPageHide

onPageHide?(): void

页面每次隐藏时触发一次,包括路由过程、应用进入后台等场景,仅@Entry装饰的自定义组件生效。

onBackPress

onBackPress?(): void | boolean

当用户点击返回按钮时触发,仅@Entry装饰的自定义组件生效。

参考资料

阿里图标库[1]

这样自定义组件的使用就完成了。

注意事项

1.自定义组件只有被导出,才可以被别的组件使用

2.自定义组件中的变量,后期不修改的话,推荐用private修饰,提高程序性能。

3.如何让自定义组件预览,我们可以加个@Preview装饰器

完整代码

定义:

代码语言:javascript复制
@Preview
@Component
export struct SettingComponent {
  private img: Resource = $r("app.media.yx")
  private title: string = "标题"
  private itemOnClick = (event: ClickEvent) => {
  } //item的单击事件(可选)

  build() {

    Row() {
      Image(this.img).width(50).margin({
        left: 40, right: 20
      })
      Text(this.title).fontSize(30).fontWeight(800)
      Blank()
      Image($r("app.media.back")).width(50)
    }.width("100%").backgroundColor(Color.White).margin({
      bottom: 10
    }).onClick((event: ClickEvent) => {
      this.itemOnClick(event)
    })

  }
}

使用

代码语言:javascript复制
import router from '@ohos.router'
import { SettingComponent } from '../com/SettingComponent'

@Entry
@Component
struct SettingPage {
  @State message: string = 'Hello World'

  build() {
    Column() {

      Row() {
        Image($r("app.media.hy")).width(50).margin({
          left: 40, right: 20
        })
        Text("会员").fontSize(30).fontWeight(800)
      }.width("100%").backgroundColor(Color.White)

      Row() {
        Image($r("app.media.yx")).width(50).margin({
          left: 40, right: 20
        })
        Text("邮箱").fontSize(30).fontWeight(800)
      }.width("100%").backgroundColor(Color.White)

      Row() {
        Image($r("app.media.cg")).width(50).margin({
          left: 40, right: 20
        })
        Text("草稿").fontSize(30).fontWeight(800)


      }.width("100%").backgroundColor(Color.White)
      SettingComponent({
        title: "会员",
        img: $r("app.media.hy")
      })
      SettingComponent({
        title: "邮箱",
        img: $r("app.media.yx")
      })
      Divider().color(Color.Blue).strokeWidth(7)
      SettingComponent({
        title: "草稿",
        img: $r("app.media.cg"),
        itemOnClick:()=>{
          router.pushUrl({
            url:"pages/Index"
          })
        }
      })

    }.width("100%").height("100%").backgroundColor(Color.Orange)
  }
}

完毕。谢谢大家

参考资料

[1]

阿里图标库: https://www.iconfont.cn/search/index?searchType=icon&q=邮箱&page=1&fromCollection=1

0 人点赞