
ArkUI-X团队协作规范:UI组件命名与代码结构的“黄金法则”
引言
在鸿蒙多端开发中,团队协作效率与代码可维护性直接影响项目交付质量。然而,常见的“组件命名混乱”“代码结构分层模糊”“公共组件重复造轮子”等问题,往往成为协作瓶颈。ArkUI-X作为跨端UI框架,其组件化开发模式对团队规范提出了更高要求。本文结合鸿蒙官方最佳实践与一线团队经验,总结UI组件命名规则与代码结构分层标准,并通过真实代码示例演示如何落地执行。
一、团队协作中的典型痛点
1.1 组件命名“各自为战”
反例:同一功能的按钮组件,有的叫MyButton,有的叫CustomBtn,甚至SubmitBtn(语义冗余);
后果:其他成员无法快速理解组件用途,复用时需反复查阅文档,增加沟通成本。
1.2 代码结构“七零八落”
反例:页面组件与工具函数混放在同一目录,公共组件分散在多个模块;
后果:修改公共逻辑时需跨多个文件搜索,容易遗漏依赖,导致版本冲突。
1.3 公共组件“重复造轮子”
反例:每个业务模块都自己实现“加载中”组件,样式与交互无法统一;
后果:维护成本激增,多端适配时需逐个修改,易出现样式不一致。
二、UI组件命名规范:语义化、一致性、可扩展
2.1 命名核心原则
语义优先:组件名直接反映功能(如SearchInput表示搜索输入框,而非InputBox);
层级清晰:通用组件(跨业务)→ 业务组件(特定模块)→ 页面级组件(仅当前页面使用);
避免冗余:无需在名称中重复模块前缀(如HomeHeader→Header,因已在home目录下)。
2.2 命名规范表
类型 规范示例 错误示例 说明
通用组件 Button、Input、Modal MyButton、CommonBtn 跨业务复用,名称保持通用性
业务组件 OrderListItem、ProductCard OrderItemComponent 特定于某业务模块,名称包含业务关键词
页面级组件 HomePage、DetailPage HomePageContainer 仅当前页面使用,名称与页面强关联
工具组件 Formatter、Validator UtilTool 纯功能组件(非UI),名称突出能力
2.3 代码示例:正确命名实践
// 通用组件(跨业务):通用加载动画
@Component
export struct LoadingSpinner {
// …组件实现
// 业务组件(电商模块):商品卡片
@Component
export struct ProductCard {
@Prop goods: { name: string, price: number };
// …组件实现
// 页面级组件(首页):首页整体容器
@Component
export struct HomePage {
build() {
Column() {
SearchInput() // 复用通用组件
ProductList() // 复用业务组件
}
三、代码结构分层规范:模块化、职责分离
3.1 标准目录结构
推荐采用“三级分层+模块化”结构,确保代码职责清晰、易于维护:
project-root/
├── common/ # 通用层(跨业务模块)
├── components/ # 通用UI组件(如Button、Modal)
├── utils/ # 通用工具函数(如日期格式化、网络请求)
├── constants/ # 全局常量(如主题色、API路径)
└── styles/ # 全局样式(如公共CSS类、动画)
├── modules/ # 业务模块层(按功能划分)
├── home/ # 首页模块
│ ├── components/ # 首页专用组件(如Banner、RecommendList)
│ ├── pages/ # 首页页面(HomePage)
│ └── services/ # 首页专用服务(如获取推荐数据)
│
└── product/ # 商品模块
├── components/ # 商品专用组件(如SkuPicker、ReviewList)
├── pages/ # 商品页面(ProductDetailPage)
└── services/ # 商品专用服务(如获取商品详情)
└── entry/ # 应用入口
├── AppScope/ # 应用级状态(如全局主题、用户信息)
└── main/ # 主入口文件(MainAbility)
3.2 分层职责说明
common层:所有业务模块共享的组件、工具、常量,禁止包含业务逻辑;
modules层:按业务功能划分(如home、product),每个模块内部实现“组件→页面→服务”的闭环;
entry层:仅包含应用启动入口、全局状态管理(如AppStorage),不涉及具体业务。
3.3 代码示例:正确结构实践
// common/components/Button.ets(通用组件)
@Component
export struct Button {
@Prop text: string;
@Prop type: ‘primary’ | ‘secondary’ = ‘primary’;
build() {
Text(this.text)
.fontSize(16)
.backgroundColor(this.type === ‘primary’ ? ‘#007DFF’ : ‘#F5F5F5’)
}
// modules/home/components/ProductList.ets(业务组件)
@Component
export struct ProductList {
@Prop goodsList: Array<{ name: string, price: number }>;
build() {
List() {
ForEach(this.goodsList, (item) => {
ListItem() {
ProductCard({ goods: item }) // 复用通用业务组件
})
}
// modules/home/pages/HomePage.ets(页面级组件)
@Component
export struct HomePage {
@State goodsList: Array<{ name: string, price: number }> = [];
aboutToAppear() {
this.goodsList = fetchHomeGoods(); // 调用本模块服务
build() {
Column() {
Button({ text: '刷新', type: 'primary' }) // 复用通用组件
.onClick(() => this.refreshGoods())
ProductList({ goodsList: this.goodsList }) // 复用本模块业务组件
}
四、公共组件管理规范:封装、复用、可配置
4.1 公共组件封装原则
单一职责:一个组件仅负责一个核心功能(如LoadingSpinner只负责加载动画);
可配置性:通过@Prop暴露必要配置项(如颜色、尺寸),避免硬编码;
无状态化:组件内部不维护状态(除非必要),状态由父组件传递。
4.2 代码示例:高复用公共组件
// common/components/CustomModal.ets(可配置弹窗)
@Component
export struct CustomModal {
@Prop visible: boolean = false; // 是否显示
@Prop title: string = ‘提示’; // 弹窗标题
@Prop content: string = ‘’; // 弹窗内容
@Prop onCancel: () => void; // 取消回调
@Prop onConfirm: () => void; // 确认回调
build() {
if (!this.visible) return;
Column() {
Text(this.title)
.fontSize(18)
.fontWeight(FontWeight.Bold)
.margin({ bottom: 16 })
Text(this.content)
.fontSize(16)
.margin({ bottom: 24 })
Row() {
Button({ text: '取消', type: 'secondary' })
.onClick(() => this.onCancel?.())
Button({ text: '确认', type: 'primary' })
.onClick(() => this.onConfirm?.())
.width(‘100%’)
.justifyContent(FlexAlign.SpaceBetween)
.margin({ top: 16 })
.width(‘80%’)
.padding(24)
.backgroundColor(Color.White)
.borderRadius(8)
}
// 使用示例(业务模块中)
@Extend(Text) function warningText() {
.fontColor(‘#FF4D4F’)
@Component
struct WarningModal {
@State isShow: boolean = false;
build() {
Column() {
Button({ text: ‘显示警告弹窗’ })
.onClick(() => this.isShow = true)
CustomModal({
visible: this.isShow,
title: '警告',
content: '库存不足,请联系客服',
onCancel: () => this.isShow = false,
onConfirm: () => {
this.isShow = false;
promptAction.showToast({ message: '已联系客服' });
})
.title('库存告急') // 覆盖默认标题
.content('当前商品仅剩1件,是否继续购买?') // 覆盖默认内容
}
五、工具链支持:让规范“自动化”
5.1 代码检查工具
使用arkts-lint自定义规则,强制检查组件命名与目录结构:
// .eslintrc.json
“rules”: {
"component-naming": ["error", { "prefix": "通用组件无前缀,业务组件以模块名开头" }],
"directory-structure": ["error", { "modules": "按功能划分,禁止跨模块引用" }]
}
5.2 组件文档生成
通过arkui-doc工具自动生成组件文档,方便团队查阅:
- @description 通用加载动画组件
@props { ‘primary’ | ‘secondary’ } type - 加载动画类型(默认primary)
*/
@Component
export struct LoadingSpinner { … }
5.3 CI/CD集成
在代码提交钩子(如pre-commit)中加入规范检查,未通过则阻断提交:
.husky/pre-commit
npm run lint # 检查代码规范
npm run doc # 生成组件文档
结语
ArkUI-X团队协作规范的核心是通过标准化降低沟通成本,通过模块化提升代码复用性。统一的命名规则让组件“望名知意”,清晰的分层结构让代码“各司其职”,而公共组件的规范化封装则让团队摆脱“重复造轮子”的困境。结合工具链的自动化检查,团队可将更多精力聚焦于业务创新,而非“修修补补”的维护工作。未来,随着鸿蒙生态的壮大,遵循这些规范的团队将更高效地适应跨端开发需求,实现“一次开发,多端部署”的终极目标。
