在鸿蒙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通信实现业务解耦。掌握这套体系后,已经具备开发中大型电商级复杂页面的能力,摆脱新手式重复编码,写出规范、简洁、可维护的鸿蒙代码。

Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐