尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

HarmonyOS开发实战:笔友-CommonComponents 组件库设计哲学——聚合与拆分的权衡

HarmonyOS开发实战:笔友-CommonComponents 组件库设计哲学——聚合与拆分的权衡
📅 发布时间:2026/7/25 15:49:29

前言

在 ArkUI 声明式开发范式中,组件复用是提升开发效率和 UI 一致性的关键手段。xiexin 将 5 个通用组件集中放在一个 146 行的CommonComponents.ets文件中,这种"单文件聚合"的设计在小型项目中极具性价比,但随着项目规模增长,需要向"多文件拆分"演进。

本文将以CommonComponents.ets为蓝本,详细剖析组件库设计中的"聚合 vs 拆分"选择、组件的导出/引用机制、@Component/@Prop/@BuilderParam在组件封装中的配合,以及组件库随着项目规模增长的演进路线。

一、CommonComponents 的整体设计

1.1 文件结构

xiexin 的CommonComponents.ets位于:

entry/src/main/ets/components/CommonComponents.ets

整个文件 146 行,包含 5 个组件:

组件行数装饰器用途
AvatarComponent34@Component@Prop头像显示,首字母回退
StatusBadge22@Component@Prop信件/笔友状态标签
CardContainer19@Component@BuilderParam通用卡片容器
EmptyState49@Component@Prop空状态占位
DividerLine10@Component@Prop分割线

1.2 所有组件代码

// entry/src/main/ets/components/CommonComponents.etsimport{AppColors}from'../common/Constants';// 通用头像组件@Componentexportstruct AvatarComponent{@Propname:string='';@PropavatarSize:number=48;@PropfontSize:number=18;privategetAvatarColor():string{constcolors:string[]=['#E8D5B7','#D4C4A8','#C9B896','#BFA98A','#D1C0A5','#C2B59B'];lethash:number=0;for(leti=0;i<this.name.length;i++){hash=this.name.charCodeAt(i)+((hash<<5)-hash);}returncolors[Math.abs(hash)%colors.length];}build(){Stack(){Circle().width(this.avatarSize).height(this.avatarSize).fill(this.getAvatarColor())Text(this.name.length>0?this.name.charAt(0):'?').fontSize(this.fontSize).fontColor(AppColors.TEXT_PRIMARY).fontWeight(FontWeight.Medium)}.width(this.avatarSize).height(this.avatarSize)}}// 状态标签组件@Componentexportstruct StatusBadge{@Proptext:string='';@Propcolor:string=AppColors.PRIMARY;@PropbgColor:string=AppColors.AMBER_LIGHT;build(){Text(this.text).fontSize(11).fontColor(this.color).backgroundColor(this.bgColor).borderRadius(10).padding({left:8,right:8,top:3,bottom:3}).fontWeight(FontWeight.Medium)}}// 通用卡片容器@Componentexportstruct CardContainer{@BuilderParamcontent:()=>void;@PropcardPadding:number=16;build(){Column(){this.content()}.width('100%').padding(this.cardPadding).backgroundColor(AppColors.CARD_BG).borderRadius(16).shadow({radius:8,color:'#0D000000',offsetX:0,offsetY:2})}}// 空状态组件@Componentexportstruct EmptyState{@Proptitle:string='暂无内容';@Propsubtitle:string='';@PropshowButton:boolean=false;@PropbuttonText:string='';onButtonClick?:()=>void;build(){Column({space:16}){Column(){Text('🏔').fontSize(64).opacity(0.3)}.margin({top:60})Text(this.title).fontSize(16).fontColor(AppColors.TEXT_SECONDARY)if(this.subtitle.length>0){Text(this.subtitle).fontSize(13).fontColor(AppColors.TEXT_SECONDARY).opacity(0.7)}if(this.showButton){Button(this.buttonText).fontSize(14).fontColor(AppColors.WHITE).backgroundColor(AppColors.PRIMARY).borderRadius(24).height(40).width(140).margin({top:16}).onClick(()=>{if(this.onButtonClick){this.onButtonClick();}})}}.width('100%').justifyContent(FlexAlign.Center).alignItems(HorizontalAlign.Center)}}// 分割线组件@Componentexportstruct DividerLine{@PropmarginH:number=16;build(){Divider().strokeWidth(0.5).color(AppColors.DIVIDER).margin({left:this.marginH,right:this.marginH})}}

二、单文件聚合 vs 多文件拆分

2.1 两种模式的对比

维度单文件聚合(xiexin 当前)多文件拆分
文件数量1 个N 个
代码定位在同一文件中滚动在目录中查找文件名
组件耦合可见,便于发现耦合隐藏,独立文件
导入语句一次 import 全部每个组件独立 import
适合阶段小型项目(< 10 组件)中大型项目(> 10 组件)

2.2 导入方式的差异

// 单文件聚合:一次 import 全部import{AvatarComponent,StatusBadge,CardContainer,EmptyState,DividerLine}from'../components/CommonComponents';// 多文件拆分:每个组件独立 importimport{AvatarComponent}from'../components/AvatarComponent';import{StatusBadge}from'../components/StatusBadge';

2.3 组件库目录结构演进

// 小型项目:单文件 components/CommonComponents.ets // 中型项目:按类别拆分 components/ ├── AvatarComponent.ets ├── StatusBadge.ets ├── CardContainer.ets ├── EmptyState.ets └── DividerLine.ets // 大型项目:按模块分组 components/ ├── avatars/ │ ├── AvatarComponent.ets │ └── GroupAvatar.ets ├── badges/ │ ├── StatusBadge.ets │ └── CountBadge.ets ├── cards/ │ ├── CardContainer.ets │ └── StatsCard.ets └── states/ └── EmptyState.ets

三、@Component 的导出与引用

3.1 export struct 的语义

@Componentexportstruct AvatarComponent{@Propname:string='';@PropavatarSize:number=48;@PropfontSize:number=18;}

3.2 在页面中引用

import{AvatarComponent,StatusBadge,EmptyState}from'../components/CommonComponents';@BuilderLetterCard(letter:Letter){Row(){AvatarComponent({name:letter.penPalName,avatarSize:40,fontSize:16})Column({space:6}){Text(letter.penPalName).fontSize(16)StatusBadge({text:this.getStatusText(letter),color:AppColors.PRIMARY})}}}

四、@BuilderParam 插槽设计

4.1 CardContainer 的插槽

@Componentexportstruct CardContainer{@BuilderParamcontent:()=>void;@PropcardPadding:number=16;build(){Column(){this.content()}.width('100%').padding(this.cardPadding).backgroundColor(AppColors.CARD_BG).borderRadius(16).shadow({radius:8,color:'#0D000000',offsetX:0,offsetY:2})}}

五、计算属性在组件中的使用

privategetAvatarColor():string{constcolors:string[]=['#E8D5B7','#D4C4A8','#C9B896','#BFA98A','#D1C0A5','#C2B59B'];lethash:number=0;for(leti=0;i<this.name.length;i++){hash=this.name.charCodeAt(i)+((hash<<5)-hash);}returncolors[Math.abs(hash)%colors.length];}

六、条件渲染在组件中的应用

if(this.subtitle.length>0){Text(this.subtitle)}if(this.showButton){Button(this.buttonText)}

七、组件参数设计原则

// 好的参数设计:明确的默认值@Propname:string='';@PropavatarSize:number=48;@PropfontSize:number=18;// 可选回调函数onButtonClick?:()=>void;

八、组件库的测试策略

import{describe,it,expect}from'@ohos/hypium';describe('EmptyState',()=>{it('should display title when provided',()=>{constcomponent=newEmptyState();component.title='测试标题';expect(component.title).toBe('测试标题');});});

九、组件的扩展建议

@Componentexportstruct AvatarComponent{@Propname:string='';@PropavatarUrl:string='';@PropavatarSize:number=48;@PropfontSize:number=18;build(){Stack(){if(this.avatarUrl.length>0){Image(this.avatarUrl).width(this.avatarSize).height(this.avatarSize).borderRadius(this.avatarSize/2)}else{Circle().width(this.avatarSize).height(this.avatarSize).fill(this.getAvatarColor())Text(this.name.charAt(0)).fontSize(this.fontSize).fontColor(AppColors.TEXT_PRIMARY)}}.width(this.avatarSize).height(this.avatarSize)}}

九、组件库的版本管理策略

当组件库需要版本迭代时,推荐以下策略:

  1. 新增组件:在 CommonComponents 文件中新增组件,不影响现有组件
  2. 修改组件:修改@Prop参数时,考虑向后兼容性
  3. 废弃组件:保留旧接口,添加@deprecated注释
/** * @deprecated 请使用 NewAvatarComponent 替代 */@Componentexportstruct AvatarComponent{// 旧接口}

十、组件库的文档化

组件库的文档化是团队协作的关键:

  • 每个组件需要标注@Prop参数说明
  • 提供使用示例代码
  • 标注不兼容的变更
/** * 头像组件 * @param name 用户名,用于首字母和颜色计算 * @param avatarSize 头像尺寸(默认 48) * @param fontSize 首字母字号(默认 18) */@Componentexportstruct AvatarComponent{@Propname:string='';@PropavatarSize:number=48;@PropfontSize:number=18;}

十一、从 xiexin 看组件库设计

xiexin 的组件库设计体现了"够用就好"的原则:

  1. 单文件聚合:5 个组件,146 行,适合当前阶段
  2. @Prop 参数化:所有组件可通过参数定制
  3. @BuilderParam 插槽:CardContainer 支持内容注入
  4. 可选回调:EmptyState 的 onButtonClick 可选

提示:当组件数量超过 10 个时,建议按"组件类型"拆分到独立文件,避免单文件膨胀。

十二、组件库的 CI/CD 集成

在团队协作中,组件库的自动化测试和发布是保证质量的关键:

  1. 单元测试:每个组件需要有对应的@ohos/hypium测试用例
  2. 视觉回归测试:使用截图对比工具检测 UI 变化
  3. 自动发布:组件库可以发布为 HAR 包,供其他模块使用
// oh-package.json5 { "dependencies": { "@xiexin/common-components": "1.0.0" } }

总结

本文详细剖析了 xiexin 的 CommonComponents 组件库设计哲学,重点讲解了单文件聚合 vs 多文件拆分的权衡、@Prop 参数化设计、@BuilderParam 插槽模式,以及组件库随着项目规模增长的演进路线。

如果这篇文章对你有帮助,欢迎点赞👍、收藏⭐、关注🔔,你的支持是我持续创作的动力!


相关资源:

  • 开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net
  • HarmonyOS 应用开发指南:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/application-dev-guide
  • HarmonyOS 状态管理概述:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/arkts-state-management-overview
  • HarmonyOS 高性能编程实践:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/arkts-high-performance-programming
  • HarmonyOS 组件复用:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/arkts-component-reusable
  • HarmonyOS 自定义组件:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/arkts-custom-components
  • HarmonyOS 组件封装:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/arkts-component-encapsulation
  • HarmonyOS @Builder 装饰器:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/arkts-builder
  • HarmonyOS @BuilderParam 装饰器:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/arkts-builderparam
  • HarmonyOS 自定义组件:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/arkts-custom-components
  • HarmonyOS 组件封装:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/arkts-component-encapsulation
  • HarmonyOS @Builder 装饰器:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/arkts-builder
  • HarmonyOS @BuilderParam 装饰器:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/arkts-builderparam
  • HarmonyOS @Prop 装饰器:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/arkts-prop
  • HarmonyOS 组件复用开发实践:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/arkts-component_reuse
  • HarmonyOS 状态管理概述:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/arkts-state-management-overview
  • HarmonyOS 自定义组件生命周期:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/arkts-custom-components-lifecycle

相关新闻

  • 2026 遵义汇川漏水检测维修必须推荐全区域覆盖 - 超人防水
  • 宠物用品推荐系统
  • 文创作品线上大众评选,微信投票实操教程 - 微信投票小程序

最新新闻

  • 如何用智能助手提升英雄联盟游戏体验:5大功能完全指南
  • 温州市泰顺县2026最新黄金回收门店+黄金回收+白银回收+铂金回收店铺TOP5排行榜+联系方式指南 - 盛世金银回收
  • 武汉市城市英才学校招生老师电话_2026 补录专业咨询_报名联系方式 - 武汉中职最新信息发布
  • 2026年防爆观光车厂家哪家好维度评测梳理 - 起跑123
  • 2026年国内彩色路沿石厂家 合规资质达标 正规供应参考 - 热点速览
  • 域名与主机控制权:保障业务连续性的核心策略

日新闻

  • 从国家条件到买方清单,深入理解 ABAP CDS 单值过滤器派生
  • 2026 年当下,齐齐哈尔专业的不锈钢闸门批发厂家哪个好,揭秘!这个工业“铁门”如何实现成本翻倍的效率提升? - 行业甄选官
  • 2026阳极氧化加工厂推荐:从设备规模看硬质氧化技术的成熟应用推荐百正机械 - 栗子测评

周新闻

  • SaaS软件行业GEO实践:AI搜索时代的品牌可见性与获客新路径
  • 什么是PCTFE?医药高端包装的“防潮王牌“材料
  • 【JVM调优实战】16-可视化利器-JConsole-VisualVM-JMC

月新闻

  • 2026年6月公司网站搭建最新热门渠道测评:四大低成本/零代码平台对比+避坑
  • 【Linux】Linux arm 编译QT程序,出现expected “}“报错
  • 【MATLAB例程】四基站二维AOA定位与距离辅助增强对比仿真。基于角度观测和测距修正的固定目标平面定位精度分析

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号