目录
一、HarmonyOS 组件开发基础
二、深入 HarmonyOS 组件开发
2.1 自定义组件开发
2.2 组件与页面的生命周期
2.3 组件化开发的优势与实践
三、HPM:HarmonyOS 组件开发的得力助手
3.1 HPM 概述
3.2 HPM 的使用方法
3.3 HPM 包描述文件 bundle.json
四、HarmonyOS 组件开发与 HPM 结合实战
五、总结与展望
一、HarmonyOS 组件开发基础

在 HarmonyOS 应用开发的广袤天地里,组件开发无疑是一块重要基石,是构建用户界面的关键环节。组件,简单来说,就是屏幕上展示出来的各种元素,是构成应用界面的基本单元。就好比搭积木,每一块积木是一个组件,通过不同的组合方式,能搭建出千变万化的建筑,而组件的合理组合就能构建出功能各异、美观实用的应用界面。
HarmonyOS 中的组件丰富多样,从功能上大致可分为以下几类。显示类组件,这类组件主要负责数据展示,像我们常见的 Text(文本)组件,用于显示一段文字内容,无论是标题、正文还是提示信息都离不开它;Image(图片)组件则用于展示图片,无论是本地图片还是网络图片,都能轻松加载呈现 ,比如电商 APP 商品详情页的商品图片展示。交互类组件,它们的存在让用户与应用之间有了互动的可能。Button(按钮)组件,用户点击它可以触发各种操作,像登录按钮,点击后进行登录验证;TextField(文本输入框)组件,允许用户输入文本信息,例如在搜索框中输入关键词进行搜索 。布局类组件则是比较特殊的存在,它们决定了其他组件的展示方式,如同房间的布局规划,不同的布局方式让家具摆放各有不同。DirectionalLayout(线性布局),可以让组件按照水平或垂直方向依次排列;DependentLayout(相对布局),组件的位置基于其他组件或父容器来确定 。
在实际的应用开发中,组件开发的重要性不言而喻。它是实现应用功能和交互设计的直接手段。一个社交类应用,聊天界面中消息展示需要 Text 组件,发送消息按钮是 Button 组件,用户头像用 Image 组件展示。这些组件的合理布局与交互设计,直接影响着用户聊天体验。从代码角度看,组件开发能提高代码的复用性。将一些常用的功能模块封装成组件,在不同页面或项目中重复使用,减少重复代码编写。比如一个通用的弹窗组件,在多个页面需要提示用户信息时都能调用,节省开发时间和精力。而且组件化开发有利于团队协作,不同开发人员可以专注于不同组件的开发,提高开发效率,就像工厂流水线作业,各司其职,共同打造出完整的应用。
二、深入 HarmonyOS 组件开发
2.1 自定义组件开发
在 HarmonyOS 开发里,自定义组件是非常强大的功能。简单来讲,自定义组件就是开发者按照自身业务需求,把已有的系统组件进行组合、封装而形成的新组件。它就像是一个个性化的积木块,是根据你的独特设计打造出来的 。比如说在一个电商应用中,商品展示模块里每个商品项都包含图片、名称、价格等信息,将这些相关组件组合封装成一个 “商品展示组件”,在不同商品展示页面都能复用,这就是自定义组件的实际应用。
自定义组件有着诸多显著特点。它具备高度的可组合性,开发者可以自由地将各种系统组件按照自己的想法组合在一起,就像玩乐高积木一样,把不同形状的积木拼成独特的造型 。可重用性也是它的一大亮点,一次定义,多处使用,大大减少了重复代码的编写。一个通用的弹窗组件,在应用的多个功能模块中都能调用,提高开发效率 。它还实现了数据驱动 UI 更新,通过改变状态变量,就能轻松驱动 UI 界面的刷新,让界面与数据保持实时同步 。
开发自定义组件一般遵循以下步骤。定义组件结构,基于struct关键字来构建自定义组件,并用@Component装饰器标识,让它具备组件化的能力 。比如定义一个简单的计数器组件:
@Component
struct CounterComponent {
@State count: number = 0;
build() {
Column() {
Text(`${this.count}`).fontSize(20);
Button('+1').onClick(() => {
this.count++;
});
}
}
}
在上述代码中,我们定义了一个CounterComponent计数器组件,使用@State修饰的count变量来记录计数,build方法中通过Column布局包含一个显示计数的Text组件和一个点击增加计数的Button组件。
再就是设置组件属性和方法,通过定义属性,让组件更加灵活通用,能接收外部传入的数据;定义方法,实现组件内部的业务逻辑 。假设我们要扩展这个计数器组件,添加一个重置功能:
@Component
struct CounterComponent {
@State count: number = 0;
// 新增重置方法
resetCount() {
this.count = 0;
}
build() {
Column() {
Text(`${this.count}`).fontSize(20);
Button('+1').onClick(() => {
this.count++;
});
// 新增重置按钮
Button('Reset').onClick(() => {
this.resetCount();
});
}
}
}
这里新增了resetCount方法用于将计数器重置为 0,并在build方法中添加了一个点击调用该方法的 “Reset” 按钮。
下面通过一个实际例子 —— 待办事项列表页面开发,来更直观地展示自定义组件的基本用法 。首先,定义一个待办事项组件TodoItem:
@Component
export struct TodoItem {
@Prop text: string;
@Prop isCompleted: boolean;
build() {
Row() {
Checkbox(this.isCompleted).onChange((isChecked) => {
// 这里可以添加逻辑将状态同步到数据层
});
Text(this.text).textDecoration(this.isCompleted? TextDecoration.LineThrough : TextDecoration.None);
}.padding(10);
}
}
在这个TodoItem组件中,通过@Prop接收外部传入的待办事项文本text和完成状态isCompleted,使用Row布局包含一个Checkbox用于切换完成状态和一个显示待办事项文本的Text组件,根据完成状态设置文本的装饰线。
然后在待办事项列表页面中使用这个组件:
@Entry
@Component
struct TodoListPage {
@State todos: { text: string; isCompleted: boolean }[] = [
{ text: '学习HarmonyOS组件开发', isCompleted: false },
{ text: '完成项目文档撰写', isCompleted: false }
];
build() {
Column() {
ForEach(this.todos, (todo, index) => {
TodoItem({
text: todo.text,
isCompleted: todo.isCompleted
});
});
}.padding(20);
}
}
在TodoListPage页面组件中,定义了一个状态数组todos来存储待办事项数据,在build方法中使用ForEach循环遍历todos数组,为每个待办事项创建一个TodoItem组件实例并传入相应数据。
在开发过程中,公共组件的封装也是关键。像前面提到的TodoItem组件,如果在多个页面都有使用需求,就可以将其封装成公共组件 。一般将公共组件存放在专门的目录,比如在项目的src/main/ets/components目录下,这样便于管理和复用 。其他页面引入时,使用import语句即可,例如import { TodoItem } from '../components/TodoItem',然后就可以像在TodoListPage中一样使用这个组件了 。
2.2 组件与页面的生命周期
在 ArkUI 框架下,页面和组件都有各自的生命周期,理解它们对于开发高质量的 HarmonyOS 应用至关重要 。
先来看页面的生命周期,它是指从页面被创建到销毁的整个过程,这个过程中包含多个关键阶段 。onCreate阶段,当页面被创建时触发,就好比一个新生儿诞生,在这个阶段,我们可以进行一些重要的初始化工作,比如绑定事件监听器,为页面上的按钮绑定点击事件;或者发起数据请求,获取页面展示所需的数据 。onAppear阶段,当页面出现在屏幕上时触发,这时候页面开始展示内容,我们可以启动一些只有在页面显示时才需要执行的任务,比如播放页面中的动画 。onDisappear阶段,当页面从屏幕上消失时触发,比如用户切换到其他页面,此时可以取消一些与页面显示相关的任务,像暂停正在播放的音频 。onDestroy阶段,当页面被销毁时触发,这意味着页面的使命结束,在这个阶段,我们要释放一些占用的资源,比如解绑事件监听器,防止内存泄漏 。
组件的生命周期同样有其独特的阶段 。aboutToAppear阶段,在组件即将出现在屏幕上时回调,具体时机是在创建自定义组件的新实例后,执行其build函数之前 。这个阶段可以进行一些准备工作,比如初始化组件的一些内部状态 。onDidBuild阶段,在组件完成构建时触发,此时组件的 UI 结构已经确定,我们可以获取组件的一些属性信息 。aboutToDisappear阶段,在组件即将被销毁时执行,在这个阶段要注意,不允许改变状态变量,特别是@Link变量的修改可能会导致应用程序行为不稳定 ,这个阶段可以进行一些清理工作,比如取消网络请求 。
以一个包含父子组件的页面为例,假设父组件是ParentComponent,子组件是ChildComponent 。当页面加载时,首先触发ParentComponent的aboutToAppear,接着执行build方法构建 UI,然后触发ChildComponent的aboutToAppear,再执行ChildComponent的build方法,之后触发ParentComponent的onDidBuild和ChildComponent的onDidBuild 。当页面切换,组件即将消失时,先触发ChildComponent的aboutToDisappear,再触发ParentComponent的aboutToDisappear 。理解这些生命周期的触发顺序和作用,能帮助我们更好地管理组件和页面的状态,优化应用性能 。
2.3 组件化开发的优势与实践
组件化开发在 HarmonyOS 应用开发中有着无可比拟的优势 。它极大地提高了代码的复用性,把一些常用的功能模块封装成组件,在不同项目或同一项目的不同页面中都能重复使用 。一个通用的导航栏组件,在多个应用页面中都能直接引用,减少了重复代码的编写,节省开发时间和精力 。组件化开发还能有效降低代码的耦合度 。每个组件都有自己独立的功能和职责,相互之间的依赖关系清晰明确 。在一个社交应用中,聊天列表组件和个人资料展示组件相互独立,修改聊天列表组件的逻辑不会影响到个人资料展示组件,使得代码的维护和扩展更加容易 。从团队协作角度看,组件化开发就像工厂流水线作业,不同开发人员可以专注于不同组件的开发,提高开发效率 。前端开发人员负责 UI 组件的开发,后端开发人员专注于数据处理组件的实现,大家分工明确,共同打造出完整的应用 。
在鸿蒙开发中,组件化开发的项目目录结构通常有清晰的规划 。一般会有一个entry目录作为项目的主入口,里面包含应用的全局配置文件 。src目录存放源代码,其中main目录下又细分多个子目录 。ets目录存放 ArkTS 代码,resources目录存放资源文件,像图片、字符串资源等 。在ets目录下,还会根据功能模块划分不同的目录来存放组件代码 。components目录专门存放各种自定义组件,pages目录存放页面组件 。这样的目录结构层次分明,便于管理和维护 。
跨组件通信是组件化开发中不可避免的问题,在鸿蒙开发中有多种实现方法 。使用@Provide和@Consume装饰器是一种常用方式 。在父组件中使用@Provide定义数据,子组件通过@Consume获取该数据,实现数据的跨组件传递和同步更新 。比如在一个购物应用中,购物车组件作为父组件,使用@Provide提供购物车商品列表数据,商品详情组件作为子组件,通过@Consume获取该数据,当购物车商品列表数据变化时,商品详情组件能实时更新显示 。还可以利用应用级别的存储AppStorage 。将需要共享的数据存储到AppStorage中,不同组件都可以从中获取数据 。在一个多页面应用中,用户登录状态数据存储在AppStorage中,各个页面组件都能获取该数据,判断用户是否登录,从而展示相应的界面 。
三、HPM:HarmonyOS 组件开发的得力助手
3.1 HPM 概述
在 HarmonyOS 开发的生态系统里,HPM(Harmony Package Manager,鸿蒙包管理器 )是一个不可或缺的工具,它就像是一个智能的组件管家,为开发者提供了便捷的组件获取与管理服务 。简单来说,HPM 是华为鸿蒙推出的组件包管理器,通过它,开发者能轻松地获取各种组件及相关的编译工具链,并将其安装到本地 。它就好比一个大型的软件超市,里面陈列着各种各样的软件组件 “商品”,开发者可以根据自己的需求挑选并 “购买”(下载安装)这些组件 。
HPM 在 HarmonyOS 开发中扮演着关键角色 。对于刚接触 HarmonyOS 的新手开发者而言,它是快速上手的利器 。新手可以在 HPM 获取下载开源发行版,这些发行版就像是已经搭建好框架的房子,开发者可以在其基础上进行定制,添加或删除组件,快速构建出自己的应用 。在实际项目开发中,当需要用到一些通用的功能组件,如网络请求组件、数据存储组件时,无需从头开发,直接通过 HPM 安装即可,大大节省开发时间和精力 。而且 HPM 还能有效管理组件之间的依赖关系 。一个复杂的应用往往依赖多个组件,这些组件又可能依赖其他组件,HPM 能自动处理这些依赖关系,确保所有组件能协同工作 。就像搭建一个机器,各个零件(组件)之间的连接和配合需要精准无误,HPM 就负责协调这些零件的安装和适配 。
3.2 HPM 的使用方法
使用 HPM 获取 HarmonyOS 源码,需要按照一定的步骤进行操作 。首先要满足一些前提条件,需要在本地安装 Node.js 和 hpm 命令行工具 。Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境,为 hpm 提供了运行基础 ,就好比汽车的发动机,是 hpm 这个 “汽车” 运行的动力来源 。hpm 命令行工具则是我们操作 HPM 的直接工具,通过它输入各种命令来实现组件的获取、安装等操作 。
以小熊派 BearPi-HM Nano 发行版为例,具体操作如下 。打开终端,进入到指定目录,比如cd /home/bearpi,然后创建一个项目文件夹并进入该文件夹,执行mkdir project && cd project 。接下来初始化项目,使用hpm init -t default命令 ,这个命令就像是在搭建房子前先打好地基,初始化项目的基本结构 。初始化完成后,就可以安装小熊派 BearPi-HM Nano 发行版组件了,输入hpm i @bearpi/bearpi_hm_nano ,这里的hpm i是hpm install的缩写,意思是安装 。等待 1 – 3 分钟(具体时间根据网速不同而有所差异),当屏幕中出现 “Installed.” 字样时,就意味着代码获取完成 。整个过程就像是在网上购物,先找到购物平台(安装 Node.js 和 hpm 命令行工具),然后进入店铺(指定目录创建项目),挑选商品(选择小熊派 BearPi-HM Nano 发行版组件)并下单购买(执行安装命令),最后等待商品送达(等待代码下载完成) 。
3.3 HPM 包描述文件 bundle.json
在 HPM 的体系中,bundle.json 文件是一个非常重要的存在 。它是 HPM 包的元数据声明文件,就像是一个商品的说明书,详细记录了包的各种信息 。一个 Bundle(等同于包)中通常包含被分发的二进制文件、源代码文件、编译脚本、自身的说明文件 bundle.json、LICENSE(许可协议文本)、README.md(自述文件)、CHANGELOG.md(变更日志,可选)等内容 ,而 bundle.json 文件则对这些内容进行了系统的描述 。
从格式定义来看,bundle.json 文件是一个 JSON 格式的文件 。它包含多个属性,“name” 属性表示 HPM 部件的英文名称,由 “@” 符号、组织名称、部件名称组成,比如 “@ohos/component_name” ,就像每个人都有一个独一无二的名字,用于标识这个部件 。“description” 属性是部件描述,简单介绍这个部件的功能和用途 。“version” 属性记录版本号,明确当前部件的版本,方便开发者进行版本管理和更新 。“homePage” 属性指定部件的主页,开发者可以通过这个链接获取更多关于部件的信息 。“license” 属性说明部件的版权协议,告知开发者使用该部件需要遵循的版权规则 。“publishAs” 属性表示发布形式,一般为代码片段 “code-segment” 。“segment” 属性定义部件的代码路径,明确代码存放的位置 。“dirs” 属性记录 HPM 包的目录结构,让开发者清楚包内文件的组织方式 。“scripts” 属性定义 HPM 包需要执行的脚本,比如编译脚本等 。“component” 属性则包含了部件的详细属性信息,如部件所属子系统、为应用提供的系统能力、特性列表、适用的系统类型、ROM 和 RAM 占用、依赖的其他部件和三方开源软件等 。
假设我们要开发一个简单的 HPM 包,比如一个自定义的日志记录组件包 。在编写 bundle.json 文件时,可以这样定义:
{
"name": "@mycompany/log-component",
"description": "A custom log component for HarmonyOS applications",
"version": "1.0.0",
"homePage": "https://github.com/mycompany/log-component",
"license": "MIT",
"publishAs": "code-segment",
"segment": {
"destPath": "utils/log-component"
},
"dirs": {
"src": ["src/**"],
"test": ["test/**"]
},
"scripts": {
"build": "gulp build",
"test": "jest"
},
"component": {
"name": "log-component",
"subsystem": "application",
"syscap": ["SystemCapability.Application.Framework"],
"features": ["log-level-control", "log-output-format-customize"],
"adapted_system_type": ["standard"],
"rom": "50KB",
"ram": "10KB",
"deps": {
"components": [],
"third_party": ["lodash"]
},
"build": {
"sub_component": ["//application/utils/log-component/src"],
"inner_kits": [
{
"header": {
"header_base": "application/utils/log-component/interface/innerkits",
"header_files": ["log.h"]
},
"name": "application/utils/log-component/interface/innerkits"
}
],
"test": ["//application/utils/log-component/test"]
}
}
}
在这个示例中,我们定义了日志记录组件包的基本信息,包括名称、描述、版本等 。指定了代码路径、目录结构和执行脚本 。在 “component” 属性中,说明了组件所属子系统、提供的系统能力、特性、适用系统类型、资源占用情况以及依赖关系和编译构建配置等 。通过这样的 bundle.json 文件,其他开发者就能清楚地了解这个日志记录组件包的相关信息,并方便地使用和集成到自己的项目中 。
四、HarmonyOS 组件开发与 HPM 结合实战
为了更直观地感受 HarmonyOS 组件开发与 HPM 的强大功能,我们以一个简单的音乐播放应用开发项目为例 。假设我们要开发一个具备基本音乐播放功能的应用,能展示歌曲列表、播放 / 暂停歌曲、切换歌曲等 。
首先,使用 DevEco Studio 创建一个 HarmonyOS 应用项目 。打开 DevEco Studio,点击 “Create Project”,在模板选择中选择 “Empty Ability”,然后点击 “Next” 。设置项目名称为 “MusicPlayer”,选择项目保存路径,点击 “Finish” 。这样就创建好了一个基础的 HarmonyOS 应用项目 。
接下来,通过 HPM 获取相关组件 。在项目根目录下,打开终端,执行hpm init -t default初始化项目 。初始化完成后,假设我们需要一个网络请求组件来获取歌曲列表数据,通过 HPM 搜索并安装合适的组件,比如hpm install @ohos/http-request-component 。等待组件安装完成,此时在项目的hpm_packages目录下就能看到新安装的组件 。
在组件开发方面,我们先来开发歌曲列表展示组件SongListComponent 。在src/main/ets/components目录下新建一个SongListComponent.ets文件,代码如下:
@Component
export struct SongListComponent {
@Prop songs: { title: string; artist: string }[];
build() {
Column() {
ForEach(this.songs, (song, index) => {
Row() {
Text(song.title).fontSize(16);
Text(song.artist).fontSize(14).margin({ left: 10 });
}.padding(10).onClick(() => {
// 这里添加点击歌曲项播放歌曲的逻辑
});
});
};
}
}
在这个组件中,通过@Prop接收外部传入的歌曲列表数据songs,使用ForEach循环遍历歌曲列表,为每首歌曲创建一个包含歌曲标题和歌手的Row布局,并添加点击事件,用于后续实现歌曲播放功能 。
然后开发音乐播放控制组件MusicPlayerControlComponent ,在components目录下新建MusicPlayerControlComponent.ets文件:
@Component
export struct MusicPlayerControlComponent {
@State isPlaying: boolean = false;
playSong() {
// 这里添加实际的播放歌曲逻辑,比如调用音频播放接口
this.isPlaying = true;
}
pauseSong() {
// 暂停歌曲逻辑
this.isPlaying = false;
}
build() {
Row() {
Button(this.isPlaying? 'Pause' : 'Play').onClick(() => {
this.isPlaying? this.pauseSong() : this.playSong();
});
// 这里可以添加切换歌曲的按钮等其他控制按钮
}.padding(20);
}
}
这个组件中,使用@State定义了播放状态isPlaying,通过Button组件实现播放和暂停功能的切换,并添加了相应的点击事件处理逻辑 。
在页面中集成这些组件 。在src/main/ets/pages/MainPage.ets文件中:
@Entry
@Component
struct MainPage {
@State songs: { title: string; artist: string }[] = [
{ title: 'Song 1', artist: 'Artist 1' },
{ title: 'Song 2', artist: 'Artist 2' }
];
build() {
Column() {
SongListComponent({ songs: this.songs });
MusicPlayerControlComponent();
}.backgroundColor(Color.White);
}
}
在MainPage页面组件中,定义了一个歌曲列表状态songs,然后将SongListComponent和MusicPlayerControlComponent组件集成到页面中,分别传入歌曲列表数据和实现音乐播放控制功能 。
通过这样一个简单的音乐播放应用开发实例,我们展示了如何使用 HPM 获取组件,以及在项目中进行组件开发和集成的全过程 。从项目创建的初始化,到 HPM 获取网络请求组件,再到自定义组件的开发与页面集成,HarmonyOS 组件开发与 HPM 的结合,让应用开发变得更加高效、便捷 。
五、总结与展望
HarmonyOS 组件开发为构建丰富多样的用户界面提供了坚实基础,从基础组件的灵活运用,到自定义组件的深度开发,再到组件化开发带来的高效复用与团队协作优势,每一个环节都蕴含着开发者的无限创造力 。而 HPM 作为强大的包管理器,就像是一位得力助手,在组件获取、项目初始化以及依赖管理等方面发挥着关键作用,极大地提升了开发效率 。
通过音乐播放应用这个实战项目,我们清晰地看到了 HarmonyOS 组件开发与 HPM 结合所产生的强大力量,它们让应用开发变得更加高效、便捷 。对于广大开发者来说,不妨亲自尝试 HarmonyOS 组件开发与 HPM 的使用,在实践中不断探索创新,将所学知识运用到实际项目中 。
展望未来,随着 HarmonyOS 生态的不断完善和发展,组件开发技术也将持续演进,有望带来更多创新的组件类型和更强大的功能 。HPM 也会不断优化升级,提供更丰富的组件资源和更智能的管理功能 。相信在 HarmonyOS 的技术浪潮中,开发者们能不断创造出更多优秀的应用,为用户带来更加卓越的体验,共同推动 HarmonyOS 生态的繁荣发展 。

















暂无评论内容