HarmonyOS ArkUI 组件复用与父子组件通信
在鸿蒙ArkUI声明式开发体系中,组件复用与父子组件通信是从“基础页面编写”进阶到“工程化项目开发”的核心分水岭。规范化开发通过复用机制精简代码、统一UI风格,并通过组件通信实现页面数据驱动更新。
一、前言:为什么需要组件复用?
在开发电商首页、购物车、列表卡片等复杂页面时,页面中存在大量重复的样式、重复的UI结构、统一的交互逻辑。如果全部手写,会出现代码冗余、样式不统一、后期维护成本极高的问题。
ArkUI 提供了一套完整的复用方案:样式复用、UI结构复用、自定义组件复用,配合父子组件数据通信机制,能够实现高内聚、低耦合的前端开发模式,也是企业级鸿蒙项目模块化开发的基础。
二、三大复用装饰器对比与实战用法
(1)@Styles:全局通用样式复用
@Styles 用于抽取多个组件通用的公共样式,仅复用样式属性,不复用UI结构。适用于全局统一的字体、颜色、边距、对齐等基础样式。
核心特点:无组件绑定、全局可调用、轻量化、仅样式复用。
适用场景:统一页面文本样式、统一按钮默认样式、统一卡片边距圆角。
// 全局通用样式
@Styles
function commonText() {
.fontSize(14)
.fontColor('#333333')
.margin(10)
}
@Styles
function cardBg() {
.backgroundColor(Color.White)
.borderRadius(12)
.shadow(0.5, 10, Color.Gray)
.padding(12)
}
(2)@Extend:专属组件样式扩展
与 @Styles 不同,@Extend 绑定指定原生组件,只能作用于目标组件,可以扩展原生组件属性,甚至绑定专属交互逻辑。
核心特点:组件专属、可扩展原生能力、比 Styles 功能性更强。
适用场景:自定义专属Text文本、专属Button按钮,实现全局统一的定制化组件样式。
// 专属Text组件扩展样式
@Extend(Text) function titleText() {
.fontSize(18)
.fontWeight(FontWeight.Bold)
.fontColor('#000')
}
(3)@Builder:UI结构片段复用
@Builder 是 ArkUI 中复用UI结构的核心方案,可以封装一段重复的组件结构,支持传参、支持动态数据渲染,是页面局部复用的最优解。
同时搭配 @BuilderParam 可以实现父组件向子组件注入自定义UI片段,实现高灵活度的组件插槽效果,极大提升组件的复用性和扩展性。
适用场景:列表卡片、通用标题栏、通用空数据页面、重复弹窗结构。
// 封装通用卡片布局
@Builder
function GoodsCard(name: string, price: number) {
Column() {
Text(name).titleText()
Text(`¥${price}`).fontColor('#f56c6c').fontSize(16)
}
.cardBg()
.width('100%')
}
三、自定义组件与父子组件通信原理
单纯的结构复用只能解决代码冗余问题,想要实现数据驱动UI更新,必须依靠组件状态通信机制。在模块化开发中,页面会拆分为父组件与多个子组件,数据由父组件统一管理,子组件负责展示,通过单向数据流实现状态统一管理。
(1)核心通信装饰器:@Prop 单向传值
@Prop 用于实现父组件向子组件单向数据传递,是项目中最常用的组件通信方式。父组件使用 @State 定义状态变量,通过传参传递给子组件的 @Prop 变量。
核心机制:父组件数据更新 → 自动同步子组件 → 子组件UI自动刷新,子组件无法修改父组件数据,保证数据流单向可控,避免状态混乱。
(2)@State 与 @Prop 职责区分
很多新手误区:子组件定义大量 @State 状态。实际工程规范中:
@State:仅用于组件内部私有状态,不对外暴露
@Prop:用于接收父组件传递的业务数据,只读、可响应更新
该机制保证了数据来源唯一,是复杂页面状态不乱、易于维护的关键。
(3)购物车案例
子组件 GoodsItem.ets
@Component
export struct GoodsItem {
// 接收父组件传值
@Prop goodsName: string
@Prop goodsCount: number
build() {
Row() {
Text(this.goodsName)
Text(`数量:${this.goodsCount}`)
}
.commonText()
}
}
父组件页面使用 + 状态更新
import { GoodsItem } from './GoodsItem'
@Entry
@Component
struct Index {
// 父组件唯一数据源
@State name: string = '鸿蒙学习手册'
@State count: number = 1
build() {
Column() {
// 子组件绑定父状态
GoodsItem({ goodsName: this.name, goodsCount: this.count })
// 修改父状态,子组件自动刷新
Button('增加数量')
.onClick(() => {
this.count++
})
}
.padding(20)
}
}
四、总结
三者复用方案各司其职:样式复用统一界面、Builder 结构复用精简代码、自定义组件+Prop通信实现业务解耦。掌握这套体系后,已经具备开发中大型电商级复杂页面的能力,摆脱新手式重复编码,写出规范、简洁、可维护的鸿蒙代码。
更多推荐


所有评论(0)