鸿蒙 ArkTS 实战:Bill Due Reminder 从状态建模到交互闭环完整解析
2026/6/26 1:38:31 网站建设 项目流程

鸿蒙 ArkTS 实战:Bill Due Reminder 从状态建模到交互闭环完整解析

前言

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net

Bill Due Reminder 是一个面向生活事务管理的鸿蒙 ArkTS 小应用。面向账单金额、待支付数量和付款状态,构建家庭账单提醒面板。 本文围绕项目中的 entry/src/main/ets/pages/Index.ets 展开,拆解它的数据模型@State 状态业务方法Builder 组件和页面布局方式,帮助读者理解一个轻量鸿蒙应用如何从静态数据走向可交互页面。

图示说明:页面以卡片、列表、输入框、按钮和状态统计为主体,适合在 DevEco Studio 中作为 ArkTS 组件化练习项目。

一、项目定位与功能闭环

1.1 应用要解决的问题

Bill Due Reminder 的业务入口非常轻:用户打开页面后,先看到已有数据和统计信息,再通过输入框或按钮触发状态变化。它不是重后台项目,而是典型的单页状态驱动应用

维度项目表现技术落点
数据承载使用接口描述业务对象interface
页面状态使用 @State 保存列表、输入和开关ArkTS 状态管理
交互动作点击按钮后重建数组或修改字段不直接突变旧数组
视觉组织卡片、行组件、统计块Builder 复用
运行环境DevEco Studio + 鸿蒙 ArkTSStage 模型页面

1.2 本文阅读重点

  1. 先看数据模型,理解页面到底在管理什么。
  2. 再看状态变量,判断哪些字段会触发 UI 刷新。
  3. 接着看核心方法,梳理新增、切换、筛选、统计等动作。
  4. 最后看页面布局,把业务数据映射成用户能理解的界面。

核心观点:ArkTS 页面开发的关键不是把控件堆满,而是让数据结构、状态变化和 UI 呈现形成稳定闭环。

二、工程结构与入口文件

2.1 目录结构

本项目是标准鸿蒙工程,核心页面位于 entry/src/main/ets/pages/Index.ets。文章聚焦这个文件,因为它包含了主要模型、状态、方法和 UI。

Bill Due Reminder ├── AppScope ├── entry │ └── src │ └── main │ ├── ets │ │ └── pages │ │ └── Index.ets │ └── module.json5 ├── hvigor ├── build-profile.json5 └── oh-package.json5

2.2 页面入口

ArkTS 页面通过 @Entry 和 @Component 标记入口组件,uild() 方法负责描述 UI 树。

@Entry@Componentstruct Index{build(){Scroll(){Column(){// 页面内容}}}}

2.3 技术栈表

技术点用途在项目中的角色
ArkTS页面逻辑与类型声明主开发语言
ArkUI声明式组件构建界面
@State响应式状态驱动刷新
@Builder组件片段复用降低重复布局
Hvigor构建系统工程构建

三、数据模型设计

3.1 模型清单

源码中出现的业务模型为:$ifaceList。这些接口用于约束列表数据结构,让 UI 渲染时能明确字段来源。

interfaceBillItem{id:number;title?:string;name?:string;done?:boolean;status?:string;}

上面的代码展示了这类模型的常见形态:id 用于列表 key,名称字段用于展示,状态字段用于判断颜色、按钮文案和操作结果。

3.2 模型设计表

模型主要价值页面用途
$primaryInterface承载核心业务条目列表渲染、按钮操作
辅助模型承载记录、提示或分类详情展示、过滤统计
状态字段表示完成、提醒、选中等状态控制颜色和文案

3.3 为什么用 interface

ArkTS 中使用 interface 可以在编写对象数组时获得更强的结构约束,减少字段拼写错误。对于列表型应用,这一点尤其重要。

实践要点:如果页面中有多条同结构数据,应优先抽象成接口,再让 @State 数组保存该接口类型。

四、状态变量拆解

4.1 @State 清单

项目中的状态声明包括:$stateList。

@Stateitems:BillItem[]=[];@StatedraftText:string='';@StateselectedIndex:number=0;@Stateenabled:boolean=true;

实际源码会根据业务命名,例如列表、输入框、筛选条件、开关状态等。它们共同决定页面当前显示什么、按钮点击后更新什么。

4.2 状态分类

状态类型示例作用
列表状态$primaryState页面主体数据
输入状态draftName、keyword、nswer接收用户输入
选择状态selectedId、 ilter、cursor决定当前视图
开关状态
eminder、shared、
ecording控制功能启停
统计状态correct、wrong、seconds形成即时反馈

4.3 状态更新原则

ArkTS 页面中,列表更新常采用重建数组的方式,这样更容易触发界面刷新。

privateupdateItem(id:number):void{this.items=this.items.map((item:BillItem)=>{if(item.id!==id){returnitem;}return{...item,done:!item.done};});}

五、核心方法解析

5.1 方法清单

源码中的核心方法包括:$methodList。这些方法构成了应用的业务动作层。

方法类型常见方法说明
统计方法otal、count、verage从列表中派生数字
新增方法ddItem、ddTask从输入状态创建新对象
切换方法oggle、 inish、
ext修改完成、提醒、进度
过滤方法isible、 iltered根据关键词或分类筛选
展示方法
ow、card、sectionHeader组织 UI 片段

5.2 统计方法

很多轻量应用都需要顶部统计卡片。统计方法通常通过 ilter、
educe 或数组长度计算。

privatecountActive():number{returnthis.items.filter((item:BillItem)=>!item.done).length;}privatetotalValue():number{returnthis.items.reduce((sum:number,item:BillItem)=>sum+1,0);}

5.3 新增方法

新增逻辑的关键是从输入框状态读取文本,做空值判断,再把新对象插入列表。

privateaddItem():void{consttitle=this.draftText.trim();if(title.length===0){return;}constid=this.items.reduce((maxId:number,item:BillItem)=>Math.max(maxId,item.id),0)+1;constitem:BillItem={id:id,title:title,done:false};this.items=[item,...this.items];this.draftText='';}

5.4 切换方法

完成、提醒、收藏、订阅这类动作都可以通过 map 生成新数组。

privatetoggleItem(id:number):void{this.items=this.items.map((item:BillItem)=>{returnitem.id===id?{...item,done:!item.done}:item;});}

六、Builder 组件复用

6.1 Builder 清单

项目中的 Builder 组件包括:$builderList。

@Builder 适合承载重复出现的 UI 片段,比如统计卡、列表行、筛选按钮、章节标题等。

@Builderprivaterow(item:BillItem){Row(){Text(item.title??item.name??'未命名').fontSize(16).fontWeight(FontWeight.Medium)}.padding(12).backgroundColor('#FFFFFF').borderRadius(8)}

6.2 复用价值

Builder复用价值适用位置
统计卡片避免重复写数字和标签布局顶部概览
列表行统一条目样式主列表
筛选按钮保持选中态一致分类切换
区块标题统一标题和辅助信息页面分组

6.3 组件边界

Builder 不需要承担复杂业务判断,它更适合做“给定数据,渲染界面”。业务变化仍然放在 private 方法中。

七、页面布局结构

7.1 Scroll + Column

这批项目大多采用 Scroll 包裹 Column 的布局方式,适合移动端纵向内容流。

Scroll(){Column(){// 头部区域// 输入区域// 列表区域// 详情区域}.width('100%').padding(16)}.height('100%').width('100%')

7.2 页面分区

分区作用常用组件
头部展示标题、说明、统计Text、Row、Column
输入区接收新增数据TextInput、Button
操作区筛选、切换、开关Button、Toggle
列表区展示业务条目ForEach、Builder 行
结果区展示统计或详情Card 风格容器

7.3 ForEach 渲染

列表通常通过 ForEach 渲染,并使用 id 作为稳定 key。

ForEach(this.items,(item:BillItem)=>{this.row(item)},(item:BillItem)=>item.id.toString())

稳定 key 能减少列表刷新时的错位,也更利于后续扩展动画或局部更新。

八、交互闭环设计

8.1 从输入到列表

新增动作通常经过以下路径:

  1. TextInput 的 onChange 更新草稿状态。
  2. Button 的 onClick 调用新增方法。
  3. 新增方法创建业务对象。
  4. 列表状态重建,页面自动刷新。
TextInput({text:this.draftText}).onChange((value:string)=>{this.draftText=value;})Button('添加').onClick(()=>{this.addItem();})

8.2 从按钮到状态

切换类按钮不需要复杂表单,只要传入条目 id 即可。

Button('完成').onClick(()=>{this.toggleItem(item.id);})

8.3 状态反馈

按钮文案、颜色、标签和统计数字都来自状态。这样用户的每次点击都能马上看到反馈。

关键点:页面反馈越直接,工具应用越容易形成“点一下就知道结果”的操作感。

九、视觉层与信息层

9.1 色彩表达

项目常用白色卡片承载内容,用主题色突出主按钮,再用绿色、橙色、红色表达安全、待处理、异常等状态。

状态色彩倾向用户理解
正常绿色已完成、可用、安全
待处理橙色需要关注
异常红色需要立即处理
中性灰色普通说明

9.2 文本层级

标题使用较大字号,列表项名称使用中等字号,说明文本使用小字号。这样的层级适合小屏阅读。

Text('页面标题').fontSize(30).fontWeight(FontWeight.Bold)Text('辅助说明').fontSize(14).fontColor('#667085')

十、鸿蒙 ArkTS 开发要点

10.1 类型先行

先定义接口,再写状态数组,可以让页面开发更稳。

10.2 状态集中

当前项目把状态集中在 Index 组件内,适合轻量单页应用。随着功能增加,可以再拆分组件或引入持久化。

10.3 方法命名

源码中的 $primaryMethod 等方法名直观表达动作,有利于阅读和维护。

10.4 UI 与逻辑分离

Builder 负责渲染,private 方法负责业务动作,这种分工能让页面不至于变成一整块难读代码。

十一、运行与调试流程

11.1 使用 DevEco Studio 打开

# 使用 DevEco Studio 打开项目目录# 同步 oh-package 依赖# 选择模拟器或真机运行 entry 模块

11.2 命令行构建思路

hvigorw clean hvigorw assembleHap

11.3 调试观察点

观察点关注内容
页面是否进入@Entry 是否正常加载
列表是否刷新@State 数组是否重建
输入是否生效onChange 是否写回状态
按钮是否响应onClick 是否调用方法
样式是否稳定卡片宽度、颜色、字号是否一致

十二、可维护性拆解

12.1 文件规模

当前 Index.ets 约 80 行,属于可阅读的单页规模。随着功能继续增加,可以把列表行、统计卡和输入区拆到独立组件。

12.2 数据扩展

如果要接入本地存储,可以先为 $primaryInterface 增加序列化字段,再在页面加载时恢复列表。

interfaceStoredRecord{id:number;payload:string;updatedAt:number;}

12.3 异常边界

输入为空时直接返回,是轻量应用常见处理方式。更复杂的产品可以加入 Toast 或错误提示。

十三、同类项目迁移思路

13.1 可复用结构

Bill Due Reminder 的结构可以迁移到很多轻量工具:

  • 一组业务对象。
  • 一组页面状态。
  • 若干统计方法。
  • 一个新增入口。
  • 一个列表展示区。

13.2 抽象模板

interfaceItemModel{id:number;title:string;done:boolean;}@Stateitems:ItemModel[]=[];privateaddItem(title:string):void{this.items=[{id:Date.now(),title:title,done:false},...this.items];}

13.3 适配范围

应用类型可复用部分
清单工具列表、完成状态、统计
记录工具输入、历史、筛选
学习工具进度、得分、卡片
家庭工具提醒、状态、分组

十四、项目亮点总结

14.1 业务表达清晰

Bill Due Reminder 没有把逻辑藏在复杂框架里,而是直接用接口、状态和方法表达业务。

14.2 页面反馈及时

每个操作都会落到 @State,列表、统计和按钮状态随之变化。

14.3 结构适合继续扩展

当前结构可以自然扩展持久化、搜索、排序、通知和多页面跳转。

十五、总结

Bill Due Reminder 展示了鸿蒙 ArkTS 单页应用的典型写法:通过 $ifaceList 建模业务数据,通过 $stateList 保存页面状态,通过 $methodList 完成统计、筛选、新增和切换,再通过 $builderList 把重复 UI 片段组件化。它的价值不只是一个具体工具,而是一套可以迁移到其他轻量应用的工程组织方式。

对于正在学习鸿蒙 ArkTS 的开发者来说,这个项目适合重点观察三件事:数据模型如何约束页面、状态变化如何驱动 UI、Builder 如何让列表和卡片保持一致。掌握这三点后,就能快速搭建更多家庭、学习、办公类小工具。

如果这篇文章对你有帮助,欢迎点赞、收藏、关注,你的支持是我持续创作的动力!


相关资源:

  • HarmonyOS Developer
  • ArkTS 语言基础
  • ArkUI 声明式开发
  • DevEco Studio
  • 鸿蒙应用工程结构
  • 开源鸿蒙跨平台社区

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询