一、鸿蒙UI组件库概述
大家好,我是老张。做鸿蒙开发这些年,我最大的感触就是——组件库这东西,真的是「用的时候觉得理所当然,自己写的时候才知道坑有多深」。今天咱们就来聊聊组件库的那些事儿。
1.1 什么是组件库
说白了,组件库就是一堆可复用的UI零件。你想想看,一个App里有多少按钮、列表、弹窗?如果每个页面都重新写一遍,那不得累死?
组件库把这些常用的界面元素封装好,你拿来就能用。就像乐高积木,每个组件都是一个标准件,拼在一起就是一个完整的应用。
在鸿蒙里,组件库可以是系统自带的,比如Button、Text、List这些。也可以是我们自己封装的,比如一个带图标的卡片、一个自定义的导航栏。我个人习惯把业务相关的UI都抽成组件,这样后期维护起来轻松很多。
核心要点:组件库 = 可复用的UI单元 + 标准化的接口 + 灵活的配置
1.2 组件库的价值
我在项目中遇到过这么一件事:有个页面需要展示用户信息卡片,设计稿改了三次,每次都要改十几个文件。后来我把卡片抽成组件,改一个地方就全搞定了。这就是组件库的价值。
具体来说,组件库能带来这些好处:
- 开发效率翻倍——不用重复造轮子,写一次到处用
- 一致性有保障——所有页面用同一套组件,风格统一
- 维护成本降低——改一个组件,所有引用它的地方都生效
- 团队协作顺畅——大家用同一套规范,代码风格统一
你想想看,如果一个团队五个人,每个人写的按钮样式都不一样,那画面太美我不敢看。组件库就是解决这个问题的。
1.3 鸿蒙ArkUI框架简介
ArkUI是鸿蒙的原生UI框架。嗯,这里要注意,它和Android的XML布局、iOS的Storyboard都不一样。ArkUI用的是声明式语法,说白了就是「你想要什么,直接说就行」。
举个例子:
@Component
struct MyButton {
build() {
Button('点击我')
.backgroundColor('#007AFF')
.borderRadius(8)
.padding({ left: 16, right: 16, top: 8, bottom: 8 })
}
}
看到没?代码就是UI,UI就是代码。没有单独的布局文件,没有繁琐的findViewById。我个人觉得这种方式特别直观,尤其是做自定义组件的时候,逻辑和视图在一起,改起来很方便。
ArkUI的核心概念其实就三个:
| 概念 | 说明 | 类比 |
|---|---|---|
| @Component | 声明这是一个组件 | 就像盖房子用的砖 |
| build() | 描述组件的UI结构 | 砖怎么摆放 |
| @State/@Prop | 管理组件的数据状态 | 砖的颜色、大小 |
为什么会这样设计?因为鸿蒙要支持多设备——手机、平板、手表、电视。如果还用传统的命令式UI,适配起来会非常痛苦。声明式UI的好处是,你只管描述「长什么样」,框架负责「怎么画出来」。
1.4 自定义组件开发流程
好了,理论说完了,咱们来点实际的。自定义组件到底怎么搞?我总结了一个四步法:
- 分析需求——搞清楚这个组件要干什么,有哪些状态
- 设计接口——定义好输入参数(@Prop)和输出事件(@Event)
- 实现UI——用ArkUI的组件拼出界面
- 测试验证——在不同场景下跑一跑,看看有没有bug
我的经验:第一步最容易被忽略。我曾经直接上手写代码,结果写到一半发现需求理解错了,全部重来。所以,先想清楚再动手,能省很多时间。
举个完整的例子。假设我们要做一个「带角标的按钮」:
@Component
struct BadgeButton {
@Prop label: string = '按钮'
@Prop badgeCount: number = 0
@State private showBadge: boolean = false
build() {
Stack() {
Button(this.label)
.onClick(() => {
this.showBadge = !this.showBadge
})
if (this.showBadge && this.badgeCount > 0) {
Text(String(this.badgeCount))
.backgroundColor('#FF3B30')
.fontSize(12)
.width(20)
.height(20)
.textAlign(TextAlign.Center)
.borderRadius(10)
.position({ top: -5, right: -5 })
}
}
}
}
这个组件接收两个参数:按钮文字和角标数字。点击按钮可以切换角标的显示状态。你看,代码量不大,但功能完整。
避坑指南:我曾经在自定义组件里直接修改了父组件的状态,结果导致数据流混乱,调试了一整天。记住:子组件永远不要直接修改父组件的状态,要通过事件回调通知父组件去改。
最后说一句,自定义组件不是越复杂越好。如果一个组件超过200行代码,我建议你考虑拆分成更小的子组件。保持每个组件的职责单一,这才是好设计。
好了,这一章就到这里。下一章咱们会手把手写一个完整的自定义组件,从零开始,一步步来。