鸿蒙学习笔记 09 自定义组件

导语

引入

前面其实已经介绍过如何使用自定义组件了, 不过这里还是要记录一下, 因为这个东西是精髓, 能够熟练掌握才行.

我们再次明确为什么需要学习自定义组件: 偷懒, 为了提高代码的复用性, 减少后期代码的维护成本 !

资源准备

本文用到了一些外部的素材, 可以直接前往阿里巴巴矢量图标库进行下载:

在这里插入图片描述

其实就是一个问号的图标以及一个返回按钮的图标而已, 不需要的话你也可以用文本组件来代替, 只要能够实现自定义组件就可以.

目的

我们知道, 每个App的页面最上面, 都有一个导航栏一样的东西. 我们当然不可能每个页面都自己写一遍, 所以就需要用到自定义组件来完成了√ 不要抬杠说这个东西是自带的, 我现在就要从头实现, 不服气是不是#X&a

正式开始

实现Header组件

首先思考一下, 顶栏都有哪些东西呢? 其实也不用思考吧, 随便一搜或者看看手机上的CSDN就知道了:

网络图片
没错, 左边一个图片按钮, 中间一段文本, 右边一些其他的项目按钮. 那么就来实现这个框架吧√ 横着的一条, 所以直接使用Row()即可. 里面直接嵌套当然就可以了:

Row() {
  // 一个返回图标
  Image($r("app.media.back"))
    .width(30)
  // 文字部分
  Text("Hello World")
    .fontWeight(FontWeight.Bold)
    .fontSize(30)
  // 另外一个工具图标
  Image($r("app.media.wenhao"))
    .width(30)
}
.width("100%")
.height(70)
.shadow({ color: Color.Gray, radius: 20 })

在这里插入图片描述

注意, 这里为了让图标和文字的大小一样, 需要设置图标的width等于文字的font Size, 不然可能不会很好看.

另外, 我额外配置了一下shadow属性, 主要是为了让它看起来更加明显自然(有质感~)

接下来, 我们需要调整一下这些组件的位置. 对比一下上面的网图就知道, 左边这两个可以在一起, 但是右边的按钮是需要在右边的. 为了实现这个效果, 可以使用一个新的组件, 把最后那个按钮撑到后面去就行: Blank()组件就可以实现这一点:

在这里插入图片描述

Row() {
  Image($r("app.media.back"))
    .width(30)
  Text("Hello World")
    .fontWeight(FontWeight.Bold)
    .fontSize(30)
  // 撑开空间
  Blank()
  Image($r("app.media.wenhao"))
    .width(30)
}
.width("100%")
.height(70)
.shadow({ color: Color.Gray, radius: 20 })

基本上的代码已经完成, 我们直接把这段代码封装为一个组件就可以了. 这里有两种定义的位置, 一种是直接定义在这个页面里面, 省事. 另外一种就是定义在一个文件里面, 方便多处多次使用. 下面直接先定义在文件中.

定义在当前文件中

实话说, 感觉没啥说的, 可是我又说了什么

我们直接在Entry的上方, 定义一个新的结构体, 还是使用@Component来修饰, 但是不要写Entry装饰器, 否则会报错的. 随后在build方法中, 直接写上面这个组件就好:

@Component
struct Header {
  build() {
    Row() {
      Image($r("app.media.back"))
        .width(30)
      Text("Hello World")
        .fontWeight(FontWeight.Bold)
        .fontSize(30)
      Blank()
      Image($r("app.media.wenhao"))
        .width(30)
    }
    .width("100%")
    .height(70)
    .shadow({ color: Color.Gray, radius: 20 })
  }
}

使用的话, 和其他的组件只能说一摸一样, 直接写组件名()即可:

@Entry
@Component
struct Index {
  build() {
    Column() {
      // 使用组件
      Header()
    }
  }
}

定义在单独文件中

定义在当前文件简单是简单, 可是却忽略了其他组件也要调用的情况. 那么我们就需要把这个组件定义为一个单独的文件了√

组件文件, 我们就创建一个新的目录, 叫做Components, 专门用来储存我们定义好的一些组件.

在这里插入图片描述
当然当然, 其实名称是无所谓的, 我只是推荐见名知意; 然后我们把整个组件直接剪贴进去就好.

既然是模块化开发, 自然就需要导出这个组件, 这里和ES6一样的, 直接导出就可以了

// Commons.ets
@Component
// 导出模块结构体
export struct Header {
  build() {
    Row() {
      Image($r("app.media.back"))
        .width(30)
      Text("Hello World")
        .fontWeight(FontWeight.Bold)
        .fontSize(30)
      Blank()
      Image($r("app.media.wenhao"))
        .width(30)
    }
    .width("100%")
    .height(70)
    .shadow({ color: Color.Gray, radius: 20 })
  }
}

随后, 我们只需要在主文件, Index.ets中, 引入这个组件即可. 这里直接使用相对路径即可直接引入, 同时引入是不需要后缀名的, 自动识别

import { Header } from '../components/Commons'

@Entry
@Component
struct Index {
  build() {
    Column({ space: 20 }) {
      Header()
    }
  }
}

接下来, 恭喜~, 我们已经成功地将组件定义到了另外一个文件中.

在这里插入图片描述

实现动态传值

因为刚才的组件是写死的, 这肯定不是我们想要的效果. 这里既然是需要传入内容, 那么就是需要传入一个变量. 这里直接在结构体中, 使用private定义一个变量就可以了:

@Component
struct Header {
  private title: string = "Hello"

  build() {
    ...
  }
}

使用的时候也是非常简单, 因为这里有默认值, 所以可以直接写一个Header()完事, 也可以通过options传值:

@Entry
@Component
struct Index {
  build() {
    Column({space: 20}) {
      Header()
      Divider()
      Header({title: "Kaede"})
    }
  }
}

在这里插入图片描述

另外, 自定义组件也是可以加样式的, 和普通的组件加样式一摸一样, 比如下面这样, 更改组件颜色:

在这里插入图片描述

@Entry
@Component
struct Index {
  build() {
    Column({space: 20}) {
      Header()
        .backgroundColor(Color.Pink)
        .borderRadius(10)
        .margin(5)
    }
  }
}

成功啦, 这就是自定义组件的基础使用!

End

好啦, 恭喜你已经成功地定义并且使用自定义组件了. 不过呢, 其实与其说是结束了, 不如说刚刚开始, 这里才是学了一点点皮毛, 下篇文章更精彩~

希望本篇文章有帮到你, 下次再见★,°:.☆( ̄▽ ̄)/$:.°★

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Kaede清水枫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值