导语
引入
前面其实已经介绍过如何使用自定义组件了, 不过这里还是要记录一下, 因为这个东西是精髓, 能够熟练掌握才行.
我们再次明确为什么需要学习自定义组件: 偷懒, 为了提高代码的复用性, 减少后期代码的维护成本 !
资源准备
本文用到了一些外部的素材, 可以直接前往阿里巴巴矢量图标库进行下载:
其实就是一个问号的图标以及一个返回按钮的图标而已, 不需要的话你也可以用文本组件来代替, 只要能够实现自定义组件就可以.
目的
我们知道, 每个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
好啦, 恭喜你已经成功地定义并且使用自定义组件了. 不过呢, 其实与其说是结束了, 不如说刚刚开始, 这里才是学了一点点皮毛, 下篇文章更精彩~
希望本篇文章有帮到你, 下次再见★,°:.☆( ̄▽ ̄)/$:.°★ 。