【HarmonyOS ArkTS】 我的书架 - Case案例分享

232 阅读4分钟

【HarmonyOS ArkTS】 我的书架 - Case案例分享

Snipaste_2025-05-22_21-04-38.png

一、项目简介

这是一个基于ArkTS语言开发的HarmonyOS应用项目。项目结构清晰,包含基础常量定义、页面组件、数据模型、网络请求等模块,适合作为ArkTS入门学习案例。

二、开发环境搭建

  1. 安装DevEco Studio
  2. 创建ArkTS项目
  3. 配置模拟器或连接真机

三、项目结构解析

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' })

五、资源管理

六、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/@ConsumeRedux, MobX, React Context 等
样式系统类似 CSS,但有部分扩展和限制CSS 标准
跨平台能力面向 HarmonyOS 设备多平台(PC、Mobile、Server)
调试工具DevEco StudioChrome 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 并不困难,因为很多概念都是相通的,只是实现细节有所不同。