HarmonyOS应用开发实战(基础篇)Day11 -《组件复用》

组件复用

组件复用

在鸿蒙应用开发过程中,随着项目规模扩大,页面逻辑和 UI 结构会变得日益复杂。若将所有代码写在单一组件中,不仅会导致可读性下降 ,还会造成重复代码泛滥 ,严重违背"DRY(Don't Repeat Yourself)"原则。

因此,组件复用 成为提升开发效率、保障代码一致性、降低维护成本的关键手段。通过将通用 UI 片段(如用户卡片、商品项、消息气泡等)抽取为独立单元,我们可以在多个页面或列表中无缝复用,实现"一次编写,多处使用"。

正如你在开发中可能遇到的困惑:"这个 UI 片段散落在多个地方,修改起来太麻烦"------这正是组件化要解决的核心问题。

🎯 复用目标

  • 提高代码可维护性
  • 减少冗余逻辑
  • 支持团队协作(UI 与逻辑解耦)
  • 便于单元测试

在 ArkTS 中,官方提供了两种主流的组件复用方式:

  1. 抽取为独立组件文件(使用 @Component + @Prop
  2. 定义为自定义构建器(使用 @Builder

下面我们将分别详解这两种方式的实现细节、适用场景与注意事项。


提取到文件夹中(独立组件)

这是最常用、最推荐 的组件复用方式,尤其适用于跨页面、跨模块 的 UI 单元。其核心思想是:将一段 UI 逻辑封装成一个可接收外部数据的独立组件 ,并通过 @Prop 装饰器实现单向数据流(父 → 子)。

实现步骤

  1. 在项目目录下创建专门的组件文件夹(如 componentsui);
  2. 新建 .ets 文件(如 UserList.ets);
  3. 使用 @Component 声明组件,并通过 @Prop 接收外部传入的数据;
  4. 在需要使用的地方导入并调用该组件。
ts 复制代码
// src/main/ets/components/UserList.ets
import { User } from "../common/UserDemo"

@Component
export struct UserList {
  @Prop item: User; // 接收父组件传入的用户对象

  build() {
    Column() {
      Text('姓名:' + this.item.name)
        .fontSize(16)
        .fontWeight(FontWeight.Bold)
      Text('邮箱:' + this.item.email)
        .fontSize(14)
        .fontColor('#666')
    }
    .width('100%')
    .padding(10)
    .backgroundColor('#f9f9f9')
    .borderRadius(8)
  }
}

💡 关键点解析

  • @Prop :表示该属性由父组件传入,子组件不可修改(单向绑定),确保数据流清晰;
  • export struct:必须导出,才能被其他文件导入;
  • 路径规范 :建议将组件集中管理,如 src/main/ets/components/,便于查找与维护。

使用方式

在父组件中导入 UserList,并通过大括号 {} 传递参数(这是 ArkTS 的语法要求):

ts 复制代码
// 在 Index.ets 中使用
import { UserList } from '../components/UserList'

// ...
ForEach(this.users, (item: User) => {
  UserList({ item: item }) // 注意:必须用 { } 包裹参数
})

⚠️ 常见错误

若写成 UserList(item)(无大括号),编译器会报错,因为 ArkTS 要求具名参数必须显式声明

优势与适用场景

  • 高内聚低耦合 :组件内部逻辑封闭,仅通过 @Prop 暴露接口;
  • 支持 TypeScript 类型检查:传参时自动校验类型;
  • 可跨页面复用:如用户卡片既可用于"联系人列表",也可用于"聊天详情";
  • 便于样式统一 :修改 UserList.ets 即可全局生效。

Builder(自定义构建器)

@Builder 是 ArkTS 提供的一种轻量级 UI 复用机制 ,适用于同一组件内部 的 UI 片段提取。它本质上是一个带参数的函数 ,返回一段 UI 描述,不创建新的组件实例,性能开销极低。

实现方式

在当前组件内部定义 @Builder 方法:

ts 复制代码
// 在 Index.ets 内部
@Builder
musicBuildList(item: User) {
  Column() {
    Text('姓名:' + item.name)
      .fontSize(16)
    Text('邮箱:' + item.email)
      .fontSize(14)
  }
  .width('100%')
  .padding(10)
  .margin(5)
}

使用方式

直接在 build() 中调用,无需导入:

ts 复制代码
ForEach(this.users, (item: User) => {
  this.musicBuildList(item) // 直接调用,像函数一样
})

优势与局限

优势 局限
✅ 语法简洁,无额外文件 ❌ 仅限当前组件内部使用
✅ 零性能开销(无组件实例化) ❌ 无法跨页面复用
✅ 适合简单、高频的 UI 片段 ❌ 不支持 @State@Prop 等状态管理

📌 使用建议

  • 若某段 UI 仅在一个页面内重复出现 (如列表项、表单项),优先使用 @Builder
  • 若需跨页面共享 ,或包含复杂交互逻辑(如点击事件、状态变化),则应使用独立组件。

两种方式对比总结

特性 独立组件(@Component + @Prop 自定义构建器(@Builder
作用域 全局(可跨页面) 仅当前组件内部
数据传递 通过 @Prop(单向) 函数参数(值传递)
状态管理 支持 @State, @Link 不支持
性能开销 有组件实例化成本 几乎为零
适用场景 通用 UI 单元(卡片、按钮、弹窗) 页面内重复 UI 片段
工程结构 需新建文件,目录清晰 代码内联,快速实现

最佳实践建议

  1. 命名规范

    • 独立组件:PascalCase(如 UserCard.ets
    • Builder:camelCase(如 renderUserItem
  2. 目录组织

    复制代码
    src/main/ets/
    ├── components/       # 通用组件
    │   ├── UserCard.ets
    │   └── ProductItem.ets
    ├── pages/            # 页面组件
    └── common/           # 工具类、模型
  3. 避免过度拆分

    若某 UI 片段仅使用一次,无需强行抽取,保持代码简洁性更重要。

  4. 类型安全

    无论哪种方式,都应为参数添加 TypeScript 类型注解,如 item: User


通过合理运用 独立组件自定义构建器 ,开发者可以构建出高内聚、低耦合、易维护的鸿蒙应用架构,大幅提升开发效率与代码质量。

相关推荐
三品吉他手会点灯2 小时前
C语言学习笔记 - 20.C编程预备计算机专业知识 - 变量为什么必须的初始化【重点】
c语言·笔记·学习
sakiko_2 小时前
UIKit学习笔记1-创建项目(使用UIKit)、使用组件
笔记·学习
生信碱移2 小时前
PACells:这个方法可以鉴定疾病/预后相关的重要细胞亚群,作者提供的代码流程可以学习起来了,甚至兼容转录组与 ATAC 两种数据类型!
人工智能·学习·算法·机器学习·数据挖掘·数据分析·r语言
志栋智能4 小时前
超自动化安全:构建智能安全运营的核心引擎
大数据·运维·服务器·数据库·安全·自动化·产品运营
星幻元宇VR4 小时前
VR航空航天科普设备【VR时空直升机】
科技·学习·安全·生活·vr
_李小白5 小时前
【android opencv学习笔记】Day 2: Mat类(图片数据结构体)
android·opencv·学习
harder3215 小时前
RMP模式的创新突破
开发语言·学习·ios·swift·策略模式
weixin_514253186 小时前
428-uitars tmux
安全·web安全
maaath6 小时前
【maaath】Flutter for OpenHarmony 跨平台工程集成密码加密能力
flutter·华为·harmonyos
程序猿乐锅7 小时前
【Tilas|第三篇】多表SQL语句
数据库·经验分享·笔记·学习·mysql