鸿蒙开发之路:自定义组件实战——构建可复用的UI组件与组件间通信
自定义组件是基于ArkUI声明式语法构建的独立UI单元,它封装了特定的布局、样式和交互行为,可以在应用的不同部分多次复用。1. 组件基本结构与装饰器@Component@State userName: string = '默认用户'build() {Column() {.width(60)})@Component:将struct转换为可复用的UI组件@State:管理组件内部状态,状态变化自动触发
🌟 引言:组件化思维的价值
在现代鸿蒙应用开发中,组件化不仅是技术实现手段,更是架构设计的核心思想。通过将复杂界面拆分为独立、可复用的自定义组件,开发者能够构建出高内聚、低耦合的应用程序架构。ArkUI的组件系统让每个UI单元都能拥有独立的状态管理和生命周期,大幅提升代码的可维护性和团队协作效率。
一、自定义组件基础:从概念到实现
自定义组件是基于ArkUI声明式语法构建的独立UI单元,它封装了特定的布局、样式和交互行为,可以在应用的不同部分多次复用。
1. 组件基本结构与装饰器
@Component
struct UserCard {
@State userName: string = '默认用户'
@State isSelected: boolean = false
build() {
Column() {
Image($r('app.media.avatar'))
.width(60)
.height(60)
.borderRadius(30)
Text(this.userName)
.fontSize(16)
.fontColor(this.isSelected ? '#007DFF' : '#182431')
}
.padding(10)
.backgroundColor('#FFFFFF')
.onClick(() => {
this.isSelected = !this.isSelected
})
}
}
关键装饰器解析:
@Component:将struct转换为可复用的UI组件@State:管理组件内部状态,状态变化自动触发UI更新@Entry:标识页面入口组件(每个页面唯一)
2. 组件的导出与导入
为了实现真正的复用,组件需要支持跨文件引用:
// UserCard.ets
@Component
export struct UserCard { // 使用export关键字导出
@Prop userName: string
build() {
// 组件实现
}
}
// Index.ets
import { UserCard } from './UserCard' // 导入自定义组件
@Entry
@Component
struct MainPage {
build() {
Column() {
UserCard({ userName: '张三' })
UserCard({ userName: '李四' })
}
}
}
二、组件数据通信:多种场景下的信息流转
组件通信是组件化架构的核心,鸿蒙提供了多种数据传递机制适应不同场景。
1. 父传子:@Prop属性的单向流动
@Prop允许父组件向子组件传递数据,建立单向绑定关系:
@Component
struct ProductItem {
@Prop productName: string = '默认商品' // 父组件传递的属性
@Prop price: number = 0
@Prop isOnSale: boolean = false
build() {
Row() {
Column() {
Text(this.productName)
.fontSize(16)
Text(`¥${this.price}`)
.fontColor(this.isOnSale ? '#FF3B30' : '#000000')
.decoration({ type: this.isOnSale ? TextDecorationType.LineThrough : TextDecorationType.None })
}
if (this.isOnSale) {
Text('特价')
.fontColor('#FF3B30')
.border({ width: 1, color: '#FF3B30' })
}
}
}
}
// 父组件使用
ProductItem({ productName: '鸿蒙开发板', price: 299, isOnSale: true })
2. 子传父:@Event事件回调机制
子组件通过事件通知父组件状态变化,实现逆向通信:
// 子组件定义
@Component
struct SearchBar {
@State searchText: string = ''
@Event onSearch: (text: string) => void // 定义事件回调
build() {
Row() {
TextInput({ placeholder: '请输入关键词', text: this.searchText })
.onChange((value: string) => {
this.searchText = value
})
Button('搜索')
.onClick(() => {
this.onSearch(this.searchText) // 触发事件
})
}
}
}
// 父组件使用
@Entry
@Component
struct ProductPage {
build() {
Column() {
SearchBar({
onSearch: (text: string) => {
// 处理搜索逻辑
this.performSearch(text)
}
})
}
}
performSearch(keyword: string): void {
console.info(`搜索关键词: ${keyword}`)
// 实际搜索实现
}
}
3. 双向同步:@Link的状态共享
@Link建立父子组件间的双向数据绑定,任何一方的修改都会同步到另一方:
@Component
struct ToggleSwitch {
@Link isOn: boolean // 双向绑定
build() {
Toggle({ type: ToggleType.Switch, isOn: this.isOn })
.onChange((value: boolean) => {
this.isOn = value // 修改同步到父组件
})
}
}
@Entry
@Component
struct SettingsPage {
@State autoLogin: boolean = true // 父组件状态
build() {
Column() {
Text(`自动登录状态: ${this.autoLogin ? '开启' : '关闭'}`)
ToggleSwitch({ isOn: $autoLogin }) // 使用$符号建立双向绑定
}
}
}
三、组件组合与嵌套:构建复杂界面
通过组件的合理组合,可以构建出功能丰富且结构清晰的用户界面。
1. 容器组件的组合策略
// 基础信息展示组件
@Component
struct UserInfo {
@Prop user: UserModel
build() {
Row() {
Image(this.user.avatar)
.width(40)
.height(40)
Column() {
Text(this.user.name)
Text(this.user.title)
.fontColor('#666666')
}
}
}
}
// 操作按钮组组件
@Component
struct ActionButtons {
@Event onFollow: () => void
@Event onMessage: () => void
build() {
Row() {
Button('关注')
.onClick(() => this.onFollow())
Button('发消息')
.onClick(() => this.onMessage())
}
}
}
// 组合成用户卡片组件
@Component
struct UserProfileCard {
@Prop user: UserModel
@Event onFollow: () => void
build() {
Column() {
UserInfo({ user: this.user })
ActionButtons({
onFollow: this.onFollow.bind(this),
onMessage: () => this.sendMessage()
})
}
}
sendMessage(): void {
// 发送消息逻辑
}
}
2. 插槽机制:@Builder的灵活运用
@Builder提供了一种更灵活的组件内容定制方式:
@Component
struct CardContainer {
@BuilderParam header: () => void
@BuilderParam content: () => void
@BuilderParam footer: () => void
build() {
Column() {
// 头部插槽
if (this.header) {
this.header()
}
// 内容插槽
Column() {
if (this.content) {
this.content()
}
}
.layoutWeight(1)
// 底部插槽
if (this.footer) {
this.footer()
}
}
}
}
// 使用构建器定制内容
CardContainer() {
.header(() => {
Text('卡片标题')
.fontSize(18)
.fontWeight(FontWeight.Bold)
})
.content(() => {
Text('这是卡片的主要内容区域...')
})
.footer(() => {
Button('确认操作')
}
}
四、组件生命周期管理
自定义组件拥有完整的生命周期回调,允许开发者在特定时机执行逻辑。
1. 生命周期阶段详解
@Component
struct LifecycleDemo {
@State data: string = ''
// 组件即将出现时触发
aboutToAppear(): void {
console.info('组件即将显示')
this.loadData()
}
// 组件即将消失时触发
aboutToDisappear(): void {
console.info('组件即将销毁')
this.cleanup()
}
// 组件布局完成时触发
onPageShow(): void {
console.info('页面已显示')
}
// 组件隐藏时触发
onPageHide(): void {
console.info('页面已隐藏')
}
build() {
Text(this.data)
}
private loadData(): void {
// 数据加载逻辑
}
private cleanup(): void {
// 资源清理逻辑
}
}
2. 生命周期最佳实践
- 数据加载:在
aboutToAppear中执行,避免在build方法中阻塞渲染 - 资源释放:在
aboutToDisappear中清理定时器、监听器等资源 - 状态保存:在
onPageHide中保存用户操作状态
五、高级组件模式
1. 条件渲染控制
@Component
struct SmartContainer {
@Prop condition: boolean
@BuilderParam content: () => void
@BuilderParam fallback: () => void = undefined
build() {
Column() {
if (this.condition) {
this.content()
} else if (this.fallback) {
this.fallback()
} else {
Text('暂无内容')
.fontColor('#999999')
}
}
}
}
2. 列表项组件优化
@Reusable // 启用组件复用
@Component
struct OptimizedListItem {
@Prop item: ListItemModel
@Prop onItemClick: (item: ListItemModel) => void
build() {
Row() {
Image(this.item.cover)
.width(80)
.height(80)
Column() {
Text(this.item.title)
.fontSize(16)
Text(this.item.description)
.maxLines(2)
}
}
.onClick(() => {
this.onItemClick?.(this.item)
})
}
}
六、组件设计最佳实践
1. 单一职责原则
每个组件应该只负责一个特定的功能模块。过于复杂的组件应该进行拆分。
2. 接口设计规范
- 属性命名:使用驼峰命名法,明确表达意图
- 事件定义:使用
on前缀,如onValueChange - 默认值:为可选属性提供合理的默认值
- 类型校验:使用TypeScript确保类型安全
3. 性能优化策略
- 使用
@Reusable装饰器优化组件复用 - 避免在build方法中创建新对象或函数
- 合理使用
@StorageLink进行状态持久化 - 复杂计算使用
@Watch监听器优化重渲染
💎 总结
自定义组件是鸿蒙应用架构的基石。通过掌握组件通信、生命周期管理和组合模式,开发者可以构建出高度可复用、易维护的UI组件体系。良好的组件设计不仅提升开发效率,也为后续的功能扩展和维护奠定坚实基础。
本系列下一篇文章将探讨《动效与交互:属性动画、转场动画与手势处理》,深入分析如何为鸿蒙应用添加流畅的动画效果和直观的交互体验。
进一步学习建议:在实际项目中,建议从简单的展示组件开始,逐步添加交互逻辑和状态管理。官方文档中的自定义组件详解提供了完整的API参考和最佳实践示例。
需要参加鸿蒙认证的请点击 鸿蒙认证链接
更多推荐



所有评论(0)