【HarmonyOS ArkTS】 我的书架 - Case案例分享
一、项目简介
这是一个基于ArkTS语言开发的HarmonyOS应用项目。项目结构清晰,包含基础常量定义、页面组件、数据模型、网络请求等模块,适合作为ArkTS入门学习案例。
二、开发环境搭建
- 安装DevEco Studio
- 创建ArkTS项目
- 配置模拟器或连接真机
三、项目结构解析
src/main/ets/
├── constant/ # 常量定义
├── entryability/ # 应用入口能力
├── entrybackupability/ # 备份相关能力
├── models/Home/ # 数据模型
├── pages/ # 页面组件
└── request/ # 网络请求模块
四、ArkTS 核心概念实践
1. 组件化开发 - HomePage.ets
- 位于
pages/目录 - 每个页面文件对应一个功能界面
- 使用
@Entry装饰器声明为页面 - 使用
@Component装饰器声明为组件
@Entry
@Component
struct HomePage {
@State isShow: boolean = true
@State bookList: IBook[] = []
onPageShow() {
this.getBookLis()
}
getBookLis = async () => {
this.isShow = true
const result = await getBookList(CREATE_AUTHOR)
const res: IBookRes = JSON.parse(result.result as string)
this.bookList = res.data
this.isShow = false
}
build() {
Column() {
// 头部
this.HeaderBuilder()
if (this.isShow) {
LoadingProgress()
.width(50)
}
List({ space: 15 }) {
ForEach(this.bookList, (item: IBook) => {
ListItem() {
bookItem({ item })
}
.swipeAction({
end: () => {
this.itemEnd(item)
},
edgeEffect: SwipeEdgeEffect.Spring
})
.onClick(() => {
router.pushUrl({ url: 'pages/BookEditPage', params: { type: EBookType.EditBook, book: item } })
})
})
}
.padding(20)
}
.height('100%')
.width('100%')
}
@Builder
HeaderBuilder() {
Row() {
Image($r('app.media.ic_public_drawer_filled'))
.width(20);
Text('我的书架')
.fontSize(25)
Image($r('app.media.ic_public_add'))
.width(20)
.onClick(() => {
router.pushUrl({ url: 'pages/BookEditPage', params: { type: EBookType.AddBook } })
})
}
.width('100%')
.justifyContent(FlexAlign.SpaceBetween)
.height(60)
.padding(10)
.border({ width: { bottom: 2 }, color: '#f0f0f0' })
.backgroundColor(Color.White)
}
@Builder
itemEnd(item: IBook) {
Row() {
Button('删除')
.type(ButtonType.Normal)
.backgroundColor('#da3231')
.onClick(() => {
promptAction.showDialog({
title: '提示',
message: `确定要删除图书《${item.bookname}》吗?`,
buttons: [
{ text: '取消', color: '#ddd' },
{ text: '确认', color: '#ddd' }
]
})
.then(async (res) => {
if (res.index == 1) {
const res = await deleteBook(item.id)
const result: IBookRes = JSON.parse(res.result as string)
promptAction.showToast({ message: result.message })
this.getBookLis()
}
})
deleteBook
})
.height('100%')
}
}
}
容器类组件:
Column()- 垂直布局容器Row()- 水平布局容器Stack()- 层叠布局容器
Column() {
Text('标题')
.fontSize(30)
Divider()
Text('内容')
.fontSize(20)
}
.padding(10)
列表类组件:
List()- 列表容器ListItem()- 列表项ForEach()- 数据迭代渲染
List({ space: 10 }) {
ForEach(this.books, (book: Book) => {
ListItem() {
Row() {
Image($r('app.media.ic_public_book'))
Text(book.title)
.fontSize(24)
.width('80%')
Button('详情')
.onClick(() => {
Router.pushUrl({ url: 'pages/BookDetailPage' })
})
}
})
})
}
交互组件
Button()- 按钮TextInput()- 文本输入框Toggle()- 开关按钮Slider()- 滑动条
Column() {
TextInput({ placeholder: '请输入书名' })
.onChange((value: string) => {
this.inputText = value
})
Toggle({ type: ToggleType.Switch })
.onChange((isOn: boolean) => {
this.isSwitchOn = isOn
})
}
.padding(10)
2. 状态管理 - HomePage.ets
@State- 组件内部状态,被标识的变量改变会引起UI更新@Prop- 父子组件单向绑定,父向子单项传递@Link- 父子组件双向绑定,子组件可直接对父组件标识变量进行修改,数据双向通讯@Provide/@Consume- 跨层级状态共享,子孙组件可对标识变量进行修改,上层状态同步更新
@Component
struct BookItem {
@Prop title: string
@Link isFavorite: boolean
build() {
Row() {
Text(this.title)
.fontSize(20)
Toggle({ type: ToggleType.Checkbox })
.checked(this.isFavorite)
}
}
}
3. 网络请求 - request/index.ets
注意手机模拟器配置增加请求权限:
main/module.json5/
{
"module": {
"name": "entry",
"type": "entry",
"description": "$string:module_desc",
"mainElement": "EntryAbility",
"deviceTypes": [
"phone",
"tablet",
"2in1"
],
"deliveryWithInstall": true,
"installationFree": false,
"pages": "$profile:main_pages",
"abilities": [
{
"name": "EntryAbility",
"srcEntry": "./ets/entryability/EntryAbility.ets",
"description": "$string:EntryAbility_desc",
"icon": "$media:layered_image",
"label": "$string:EntryAbility_label",
"startWindowIcon": "$media:startIcon",
"startWindowBackground": "$color:start_window_background",
"exported": true,
"skills": [
{
"entities": [
"entity.system.home"
],
"actions": [
"action.system.home"
]
}
]
}
],
"extensionAbilities": [
{
"name": "EntryBackupAbility",
"srcEntry": "./ets/entrybackupability/EntryBackupAbility.ets",
"type": "backup",
"exported": false,
"metadata": [
{
"name": "ohos.extension.backup",
"resource": "$profile:backup_config"
}
],
}
],
// 网络请求权限配置
"requestPermissions": [
{
"name": 'ohos.permission.INTERNET'
}
]
}
}
封装基础的HTTP请求方法:
import http from '@kit.NetworkKit'
class Request {
private static readonly httpClient: http.HttpRequest = http.createHttp()
// GET 请求示例
static async get<T>(url: string, params?: T): Promise<IResponse> {
const response = await this.httpClient.request(url, {
method: http.RequestMethod.GET,
extraData: params
})
return JSON.parse(response.result as string)
}
// POST 请求示例
static async post<T>(url: string, data: T): Promise<IResponse> {
const response = await this.httpClient.request(url, {
method: http.RequestMethod.POST,
extraData: data
})
return JSON.parse(response.result as string)
}
}
API 接口定义
class HomeModel {
// 获取书籍列表
static async getBooks(): Promise<Book[]> {
const response = await Request.get('/api/books')
return response.data
}
// 添加新书
static async addBook(book: Book): Promise<string> {
const response = await Request.post<Book>('/api/book', book)
return response.message
}
}
接口调用示例
@Component
struct HomePage {
@State books: Book[] = []
aboutToAppear() {
this.loadData()
}
async loadData() {
try {
const result = await HomeModel.getBooks()
this.books = result
} catch (error) {
Logger.error('加载书籍失败:', error)
}
}
build() {
List({ space: 10 }) {
ForEach(this.books, (book: Book) => {
ListItem() {
Text(book.title)
.fontSize(24)
}
})
}
}
}
4. 路由跳转 - 页面导航
import { router } from '@kit.ArkUI'
router.pushUrl({ url: 'pages/BookEditPage' })
五、资源管理
- 图片资源:
resources/base/media/ - 配置文件:
resources/base/profile/ - 主题颜色:resources/base/element/color.json
六、ArkTS 与 Web 前端开发对比
| 特性 | ArkTS (HarmonyOS) | Web 前端 |
|---|---|---|
| 语言 | TypeScript 扩展 | JavaScript/TypeScript |
| 运行环境 | HarmonyOS SDK | 浏览器 |
| UI 构建方式 | 声明式 UI 组件 | HTML/CSS + JS 或 JSX |
| 通信协议 | 支持 HTTP/HTTPS 及系统级 IPC | 主要使用 HTTP(S) |
| 状态管理 | @State, @Prop, @Link, @Provide/@Consume | Redux, MobX, React Context 等 |
| 样式系统 | 类似 CSS,但有部分扩展和限制 | CSS 标准 |
| 跨平台能力 | 面向 HarmonyOS 设备 | 多平台(PC、Mobile、Server) |
| 调试工具 | DevEco Studio | Chrome DevTools, VSCode 等 |
1. 语法风格差异
- ArkTS 更接近原生开发体验,采用声明式语法构建 UI。
- Web 前端 通常需要结合 HTML、CSS 和 JS 三种语言,采用命令式语法构建 UI。
<!-- Web 前端示例 -->
<div class="container">
<button onclick="handleClick()">点击</button>
</div>
<style>
.container { padding: 10px; }
</style>
<script>
function handleClick() {
alert('按钮被点击');
}
</script>
// ArkTS 示例
@Component
struct MyButton {
build() {
Column() {
Button('点击')
.onClick(() => {
AlertDialog.show({ message: '按钮被点击' })
})
}
.padding(10)
}
}
2. 性能与集成度
- ArkTS 提供了更贴近系统的开发能力,可以直接调用 HarmonyOS 的 API,性能更优。
- Web 前端 在浏览器环境中受限较多,对硬件访问能力有限。
3. 生态与社区支持
- Web 前端 拥有庞大的开发者社区和丰富的第三方库。
- ArkTS 是较新的技术,生态正在快速成长中,官方提供了较为完善的开发工具链。
七、总结
通过上述内容,我们可以看到 ArkTS 在 HarmonyOS 开发中的优势以及它与传统 Web 前端的区别。ArkTS 结合了 TypeScript 的强大类型系统和声明式 UI 的简洁性,使得开发者能够高效地创建高性能的应用程序。对于熟悉前端开发的人来说,学习 ArkTS 并不困难,因为很多概念都是相通的,只是实现细节有所不同。