前言

大家好,我是完美句号!欢迎来到 HarmonyOS 5 开发实战系列。本系列致力于为开发者提供实用的技术方案和即拿即用的代码示例,帮助大家快速掌握 HarmonyOS Next 应用开发中的核心功能。在HarmonyOS 5鸿蒙系统中,与鸿蒙生态的原生交互设计相适配,在导航、图表、表单与提示反馈等常见界面模式上保持一致的体验准则,从而降低学习成本并提升整体的产品质感。结合 ArkUI 的声明式开发模型,开发与迭代可以更快速、更稳定地推进。

随着敏捷开发的普及,越来越多的团队将“提升效率”与“保证质量”并重对待,尤其在处理重复项目的增量开发时,通用 UI 组件愈发重要。一个成熟的组件库不仅能够提升研发效率与用户体验,还能在跨团队协作中提供统一的视觉与交互规范,保证交付的一致性与可维护性。

img

组件库的价值体现在标准化与复用化:统一的 API 与设计规范、明确的样式约束、可预期的交互行为,让开发者在清晰文档的支撑下进行高度复用,避免重复造轮子。研发可以更聚焦在业务逻辑而非基础能力的重复实现上,就像搭积木一样拼装业务功能模块,从而在大型项目与跨角色协作中显著提升一致性与交付质量。

在鸿蒙生态快速崛起的背景下,建立一套可靠的组件体系尤为关键。它不只是“现成控件”的集合,更是设计系统的落地,包括主题与品牌色、可访问性考量、状态规范、动效节律等。良好的组件体系能降低上手成本,减少样式漂移与技术债积累,为后续的规模化维护提供坚实基础。


传统鸿蒙项目开发的困境

从 HarmonyOS Next 版本之后,华为手机将不再兼容安卓 APP。许多团队需要将原有 iOS 与安卓应用迁移至鸿蒙生态,甚至进行内部转岗以适配新的技术栈,这对研发效率与工程质量提出了更高要求。

随着鸿蒙生态的完善,越来越多的企业选择将原有 iOS、安卓、uni-app 等应用迁移到这一全新的平台。然而,传统迁移方式往往需要从零重写 UI 层,不仅工作量巨大,还容易在转换过程中引入新的问题,开发与测试成本随之攀升。不同平台在视觉语言、动效节律、手势交互与系统能力上存在天然差异,简单的“平移式迁移”很难满足原生体验与性能要求。

img

在传统开发模式下,开发者经常需要重复实现基础控件、处理复杂的适配与交互逻辑,这不仅拖慢项目进度,也让质量保障变得困难。以 Web 开发为例,后台管理系统常借助 element-UI、iView、Ant Design 等组件库快速构建表格与弹窗;移动端 H5 场景常用 Vant 来简化表单与校验;小程序端则广泛采用 weiUI、uni-app 的 uView 或 taro UI 等方案,以提高效率。由此可见,可靠的组件库在不同端的开发体系中都是效率与一致性的关键杠杆。

面向内部用户的后台系统通常对视觉精致度要求相对较低,而 C 端产品更强调品牌风格与体验差异,往往需要保留更灵活的手动样式与布局定制。但即便如此,通过“样式穿透”等技术仍可在组件库基础上进行外观调整,并与设计系统保持整体一致。

因此,在鸿蒙应用的规模化落地过程中,传统迁移不仅耗时费力,还需解决兼容性与适配等问题。如何以更低成本、更高效率构建符合鸿蒙设计规范的现代化应用,成为每个 App 团队必须面对的课题。尽管 ArkUI 框架具备强大的跨端能力,但社区尚缺乏足够成熟的企业级组件解决方案——这正是 OmniUI 发力的方向。

img

为此,OmniUI 作为 58 安居客房产无线团队开源的鸿蒙 ArkUI 组件库,深度融合鸿蒙原生能力,提供 25+ 开箱即用且高扩展的组件,覆盖视图、表单、导航、图表等核心场景。无论是信息卡片还是数据可视化图表,OmniUI 都能提供一站式支持,显著提升开发效率,降低迁移与迭代成本。

img

从开发者视角看,OmniUI 不仅提供“能用”的基础控件,更注重“好用”的工程实践:合理的模块组织、清晰的 API 约定、适度的可配置能力以及贴合鸿蒙生态的交互设计,让团队可以将更多精力投入在差异化业务上,而不是重复的基础实现与适配工作。


OmniUI 组件库介绍

OmniUI 是 58 同城房产无线团队推出的鸿蒙 ArkUI 组件库,专为鸿蒙开发设计,强调一致性、可扩展性与工程可维护性,致力于为开发者提供稳定且高效的组件化基础设施。

OmniUI 提供预先设计的界面组件(如按钮、表单、表格、导航与图表),开发者可以直接使用这些组件快速构建用户界面。组件内置样式与交互逻辑,能显著提升开发效率与一致性,并在不同设备形态下保持良好的表现与体验。

img

OmniUI 的设计理念强调“统一、可预期与渐进增强”。统一的交互与视觉风格确保应用整体一致性;可预期的 API 语义降低上手成本与沟通成本;渐进增强的能力设计使组件既能满足常见场景,又为复杂业务留出合理扩展空间。性能层面,组件基于鸿蒙原生能力构建,通过按需引入与合理的状态更新策略保持运行流畅。工具与文档方面,项目持续完善示例与说明,帮助团队快速接入与落地。

在如今快速崛起的鸿蒙生态里,高质量的组件库将成为效率倍增器。借助标准化的 API、主题能力与样式约束,研发团队能够更好地控制复杂性,避免样式漂移与工程碎片化,形成“设计—开发—交付—回收”的良性闭环。

img

相关链接:

OmniUI 官方站点:https://wuba.github.io/omni-ui/

OmniUI GitHub:https://github.com/wuba/omni-ui

OmniUI 三方库地址:https://ohpm.openharmony.cn/#/cn/detail/@wuba58/omni-ui@wuba58%2Fomni-ui


OmniUI 的主题能力支持在不改动组件代码的前提下统一品牌色与字体规范,通过主题标记与样式约束将“设计系统”落地为可执行的工程约定,从而减少视觉漂移并提升跨团队协作效率。为保障可访问性,组件在色彩对比与焦点状态上遵循清晰的层级与状态表达,帮助用户在不同设备与环境下获得一致的使用体验。

如上图所示,ArkUI 自定义具备更高的自由度,适用于极端个性化场景;而 OmniUI 通过对常见交互与样式的封装,显著降低了实现成本与沟通成本,更利于标准化与规模化交付。在多数企业级场景中,二者并非对立关系:以 OmniUI 覆盖 80% 的常规需求,再通过 ArkUI 的自定义能力精细打磨剩余 20% 的差异化体验,能够在效率与品质之间取得良好平衡。

OmniUI 安装

初始化 OpenHarmony 项目

在 DevEco Studio 中新建空白项目,选择 Ability 模板进行初始化。配置项目名称、Bundle 名称与编译 SDK 版本(如 5.0.5/17),并选择设备类型(如 Phone)。点击 Finish 后,IDE 会自动完成依赖安装与初始化。

完成后,一个空白的 OpenHarmony 项目即创建完成。随后即可安装并引入第三方组件库 OmniUI,开始编写业务代码。

在模块中通过 ohpm 安装 OmniUI

确认 ohpm 可用并查看版本后,在需要的 har/hsp 模块中执行安装:


ohpm install @wuba58/omni-ui

为确保安装顺利,建议提前检查网络代理与镜像配置,保持 ohpm 源可访问;在多模块项目中,注意在目标模块下执行安装,以便依赖关系与打包配置一致。若安装失败,可尝试清理缓存并重新安装,或参考仓库的安装指引更新 ohpm 版本。


实践:快速构建社区类 APP

以社区类应用为例,底部导航是常见的入口形式。通过 OmniUI 的 TabBar 能够快速搭建底部导航并集成页面切换逻辑。在实际项目中,底部导航不仅是页面跳转的“枢纽”,也是品牌识别与功能分类的“信息索引”,需要兼顾可达性与清晰度,并在选中与非选中状态下保持明确的视觉区分。

方案一:基于 ArkUI Tabs 自定义底部导航

在 ArkUI 中,可以使用 Tabs 组件配合 TabContent 来搭建底部导航结构,并通过 barPosition 控制导航位置。各页面作为组件导入并加载到对应的 TabContent 中。

在样式层面,可使用 @Builder 修饰方法构造自定义 Tab 项,控制图标与文案的布局与选中态样式,通过条件渲染切换不同状态的资源;若需要特殊形状(如圆角或梯形),可预置切图并按索引动态切换,从而兼顾品牌风格与识别度。

交互方面,使用 TabsController 管理切换逻辑,结合 @State 记录当前选中索引,并根据生命周期方法(如 onPageShow)处理页面状态。设置 scrollable(false) 可以禁止滑动切换,仅通过点击导航项进行切换,以减少误触与状态失焦。对于带徽标的场景,可在业务逻辑中动态更新对应项的角标信息,提示未读消息或待办状态。

示例代码:


import Home from "../pages/home/Home"

import Record from "../pages/record/Record"

import My from "../pages/my/My"

@Entry

@Component

struct Index {

@State currentIndex: number = 0

private controller: TabsController = new TabsController()

// 只有被@Entry装饰的组件才可以调用页面的生命周期

onPageShow() {

console.info('Index onPageShow');

}

// 只有被@Entry装饰的组件才可以调用页面的生命周期

onPageHide() {

console.info('Index onPageHide');

}

// 只有被@Entry装饰的组件才可以调用页面的生命周期

onBackPress() {

console.info('Index onBackPress');

}

build() {

Column() {

Tabs({

barPosition: BarPosition.End,

controller: this.controller

}) {

TabContent() {

Home()

}.tabBar(this.TabBuilder('工作台', 0, $r('app.media.icon_sort'), $r('app.media.icon_sort_default')))

TabContent() {

Record()

}.tabBar(this.TabBuilder('展业记录', 1, $r('app.media.search_select'), $r('app.media.search_defaut')))

TabContent() {

My()

}.tabBar(this.TabBuilder('我的', 2, $r('app.media.user_selected'), $r('app.media.user')))

}.scrollable(false) // 禁止滑动切换

}

.width('100%')

.height('100%')

}

// 自定义导航页签的样式

@Builder TabBuilder(title: string, targetIndex: number, selectedImg: Resource, normalImg: Resource) {

Column() {

Image(this.currentIndex === targetIndex ? selectedImg : normalImg)

.size({ width: 25, height: 25 })

Text(title)

.fontColor(this.currentIndex === targetIndex ? '#1669E3' : '#2B323E')

}

.width('100%')

.height(50)

.justifyContent(FlexAlign.Center)

.onClick(() => {

this.currentIndex = targetIndex

this.controller.changeIndex(this.currentIndex)

})

}

}

方案二:使用 OmniUI 底部导航组件

OmniUI 封装了底部导航的构建逻辑,通过 OmniBottomTabBar 提供丰富的配置项(如文字颜色、图标大小、角标等),可快速实现底部导航并完成页面切换。在组件层将常见的交互与样式约束为可配置项,可以减少重复实现的时间,让开发者专注在业务路由与状态管理上。


import { OmniBottomTabBar, OmniBottomBarItem, BarTextModifier, BarIconModifier } from "@wuba58/omni-ui";



@Entry

@Component

struct Index {

@State message: string = 'Hello World';

@State barItem: OmniBottomBarItem[] = [

{

text: "工作台",

icon: $r('app.media.workspace')

},

{

text: "展业记录",

icon: $r('app.media.record')

},

{

text: "我的",

icon: $r('app.media.my')

}

]



build() {

Column() {

OmniBottomTabBar({

data: this.barItem,

defaultSelectedIndex: 1,

textModifier: new BarTextModifier().withFontColor('#2B323E'),

// textSelectedModifier: new BarSelectTextModifier().withFontColor(Color.Blue),

// iconSelectedModifier: new BarSelectedIconModifier().withBackgroundColor(Color.Green),

iconModifier: new BarIconModifier().withHeight(30),

}).width('100%').margin({ top: 10 }).height(80)

}

.width('100%')

}

}

实际项目中,底部导航承载频繁的页面切换与状态反馈,优先采用“明确的选中态颜色与图标反馈”,并在角标提示上注意“重要信息优先、可达性友好”的原则。对于存在多入口的业务组块,建议在文案上使用动词与对象组合的结构(如“展业记录”),让用户能快速建立认知并减少误触。

从 ArkUI 的自定义底部导航到 OmniUI 的封装组件,可以看到后者在封装程度与可配置性上更具优势。以常见的未选中、选中、徽标等场景为例,OmniUI 通过配置即可实现,大幅压缩开发时间:从约 20 分钟缩减到约 5 分钟,效率提升明显。在团队维度,这种“可复用的抽象”也降低了培训成本与评审沟通成本,让规范更容易被执行与传承。

在动效节律上,建议采用细微但可感知的过渡与缩放反馈,在选中态与页面切换间保持一致的时间参数与缓动曲线,既避免突兀,也减少视觉疲劳。对于无障碍场景,应确保底部导航项的触达区域足够大,并在焦点状态与读屏提示上提供明确文本,让不同能力的用户都能顺畅完成导航任务。文案层面,尽量保持短句与行动导向,避免过度修饰与同义重复,提升信息传达的效率。


折线图:实现与差异

当前 ArkUI 尚无开箱即用的图表组件,通常需通过绘制组件或画布组件实现,这对开发者的计算与绘图逻辑提出较高要求。相比之下,OmniUI 提供折线图、柱状图等图表组件,只需通过配置即可快速完成图表展示,适用于趋势分析、对比分析与结构分析等常见场景。

在趋势分析场景中,折线的颜色与粗细应与信息层级保持一致:核心指标采用更高显眼度的主色,辅助指标使用中性灰或较低饱和度的对比色。图例位置与间距建议与数据密度相匹配,避免因过度拥挤影响辨识;对于移动端小屏设备,可在横轴标签上采用“缩略日期”与“滚动查看”的方式保证阅读流畅。

示例代码:


import { LineDataType, OmniLineChart, Options, OmniBottomTabBar, OmniBottomBarItem, BarTextModifier, BarIconModifier } from "@wuba58/omni-ui";



@Entry

@Component

struct Index {

@State message: string = 'Hello World';

@State barItem: OmniBottomBarItem[] = [

{

text: "工作台",

icon: $r('app.media.workspace')

},

{

text: "展业记录",

icon: $r('app.media.record')

},

{

text: "我的",

icon: $r('app.media.my')

}

]

@State title: string = "营收趋势";

@State insuredData: number[] = [102, 20, 123, 201, 23, 102, 310].reverse();

@State reinsuredData: number[] = [203, 290, 29, 23, 220, 29, 32].reverse();



@State defOption: Options<LineDataType> = new Options({

padding: {

top: 200,

left: 0,

right: 200,

bottom: 200

},

legend: {

left: '39%',

itemGap: 80

},

xAxis: {

type: 'category',

data: ['8月24号', '8月25号', '8月26号', '8月27号', '8月28号', '8月29号', '8月30号'],

},

yAxis: {

type: 'value',

name: ''

},

series: [

{

name: '参保人数',

lineStyle: {

width: 2

},

color: '#1D64E3',

data: this.insuredData

},

{

name: '退保人数',

lineStyle: {

width: 2

},

color: '#687A9A',

data: this.reinsuredData

}

]

});



build() {

Column() {

OmniLineChart({

options: this.defOption,

}).padding({ left: 20 }).height(400)

OmniBottomTabBar({

data: this.barItem,

defaultSelectedIndex: 1,

textModifier: new BarTextModifier().withFontColor('#2B323E'),

// textSelectedModifier: new BarSelectTextModifier().withFontColor(Color.Blue),

// iconSelectedModifier: new BarSelectedIconModifier().withBackgroundColor(Color.Green),

iconModifier: new BarIconModifier().withHeight(30),

}).width('100%').margin({ top: 10 }).height(80)

}

.width('100%')

}

}

在对照 UI 效果时,仍有部分差异尚未实现,例如折线的弯曲效果、路径上的圆点标记以及图例形状的圆形化。关于图例样式,官方文档尚未提供直接的 API;从源码数据结构来看,图例的默认配置如下:


// 图例的默认数据

const legend: LegendInterface = {

show: true,

left: '50%',

top: '1%',

itemGap: 10, // 图例每项之间的间隔。横向布局时为水平间隔,纵向布局时为纵向间隔。

itemTextGap: 5, // 图例图例之间的间隔。

itemWidth: 16, // 图例标记的图形宽度。

itemHeight: 8, // 图例标记的图形高度。

orient: 'vertical', // 图例列表的布局朝向。 可选:'horizontal''vertical'

textStyle: legendTextStyle

}

img

针对这些差异,可以考虑在业务层做轻量的增强处理:例如在折线图上方叠加自定义绘制层以模拟圆点标记,或通过调整曲线采样策略实现更接近设计稿的弯曲效果。此外,也可向组件库社区提交 Issue 或参与贡献,共同完善图表的样式与功能能力。随着版本演进,这类可视化组件通常都会逐步增加更多的配置项与表现能力。

迁移到鸿蒙生态通常伴随架构与流程的同步调整。通过“功能盘点—策略评估—UI 重构与 ArkUI 接入—集成 OmniUI—测试与优化—发布与迭代”的节奏推进,可以在保证体验质量的前提下稳步落地。将组件库与设计系统联动,把主题与交互规范内化为工程约束,能有效降低返工与视觉漂移。


总结

OmniUI 在封装程度与可配置性上表现出色,能够通过简单配置满足底部导航、视图展示与数据可视化等常见场景,显著提升开发效率。在底部导航与图表的实践中,OmniUI 将部分原生需要自定义开发的能力直接产品化,可在特定场景下带来可观的效率提升,常见情况下约能提升到 60% 左右。

img

在工程实践中,建议将组件库与设计系统配套使用:通过统一的主题、样式约束与交互规范,降低视觉漂移与实现分歧;在复杂业务中,优先采用组件的可配置能力覆盖大部分需求,再以“轻扩展、少定制”的方式保留差异化空间。对于图表类组件的细节差异,可通过小步试错与社区反馈的方式逐步完善。整体而言,OmniUI 是值得投入与使用的优秀组件库,结合实际需求进行适配与扩展,能更好地服务于鸿蒙应用的落地与规模化建设。

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐