鸿蒙 ArkTS 实战:EV Charging Spots 从出行记录到状态反馈完整解析
鸿蒙 ArkTS 实战:EV Charging Spots 从出行记录到状态反馈完整解析
前言
EV Charging Spots 是一个面向 出行管理与通勤习惯 的鸿蒙 ArkTS 小应用。记录出行条目、站点信息和提醒备注,适合日常出行复盘。 本文基于 entry/src/main/ets/pages/Index.ets 的真实源码结构展开,重点分析 interface 模型、@State 状态、业务方法、Builder 卡片 和页面布局,形成可直接发布的技术文章。

图示说明:页面以出行记录、行动打卡、状态反馈和历史卡片为主体,适合作为 ArkTS 出行类单页应用示例。
一、应用定位与业务闭环
1.1 场景定位
EV Charging Spots 把一个具体出行习惯场景做成可操作页面。用户可以记录数据、查看当前状态、执行打卡或复查动作,并通过卡片列表保留过程记录。
| 业务环节 | 页面表现 | ArkTS 实现 |
|---|---|---|
| 数据记录 | 输入、按钮、卡片 | @State + ForEach |
| 当前状态 | 数值、消息、开关 | 状态字段驱动 |
| 行动反馈 | 完成、复查、勾选 | private 方法 |
| 历史复盘 | 列表卡片 | Builder 渲染 |
| 目标追踪 | 目标值和完成度 | 派生计算 |
1.2 阅读路径
- 看接口,明确记录对象。
- 看状态,明确页面刷新来源。
- 看方法,明确用户动作。
- 看 Builder,明确 UI 复用方式。
工程判断:出行类工具的重点不是复杂页面,而是让记录、状态和反馈之间保持一致。
二、工程结构与入口页面
2.1 文件结构
核心文件是 entry/src/main/ets/pages/Index.ets。
EV Charging Spots
├── AppScope
├── entry
│ └── src
│ └── main
│ ├── ets
│ │ └── pages
│ │ └── Index.ets
│ └── module.json5
├── hvigor
└── oh-package.json5
2.2 页面入口
@Entry
@Component
struct Index {
build() {
Column() {
// 出行记录与状态反馈
}
}
}
2.3 技术组成
| 技术点 | 作用 | 价值 |
|---|---|---|
| ArkTS | 类型与逻辑 | 管理出行数据 |
| ArkUI | 声明式 UI | 构建页面卡片 |
| @State | 响应式状态 | 驱动即时反馈 |
| @Builder | UI 复用 | 统一卡片结构 |
| Hvigor | 构建系统 | 编译运行应用 |
三、数据模型设计
3.1 接口清单
源码中的接口包括:ChargeSpot。
interface ChargeSpot {
name: string;
price: string;
idle: number;
nav: string;
}
const sample: ChargeSpot = { name: 'Mall B2 fast charge', price: '1.35 per kWh', idle: 4, nav: '1.8 km away' };
接口会承载情绪、饮食、运动、午睡、出行档案、护理记录、补给节点或体检指标等业务对象。
3.2 字段职责
| 字段类别 | 常见字段 | 作用 |
|---|---|---|
| 标识字段 | id | 列表 key |
| 名称字段 | itle、 | |
| ame | 卡片主标题 | |
| 数值字段 | score、 loors、minutes | 出行指标 |
| 状态字段 | done、checked、bnormal | 结果判断 |
| 文案字段 | message、suggestion、contact | 反馈说明 |
3.3 建模收益
接口建模能让出行记录具备稳定结构。后续扩展本地存储、图表、提醒或分享时,可以直接围绕模型字段处理。
四、@State 状态拆解
4.1 状态清单
源码中的状态包括:spots、name、price、idleText、selected。
@State records: ChargeSpot[] = [];
@State draftText: string = '';
@State message: string = '';
@State enabled: boolean = true;
4.2 状态分类
| 状态类型 | 示例 | 用途 |
|---|---|---|
| 列表状态 | $primaryState | 保存记录或节点 |
| 输入状态 | draft、 riggerDraft、symptomDraft | 接收用户输入 |
| 数值状态 | loors、goal、sitting、seconds | 形成指标 |
| 开关状态 | larmOn、privacyLock、offline | 控制功能模式 |
| 反馈状态 | message、suggestion、 | |
| eminder | 呈现结果 |
4.3 更新方式
private updateItem(id: number): void {
this.records = this.records.map((item: ChargeSpot) => {
return item.id === id ? { ...item, done: true } : item;
});
}
五、核心方法解析
5.1 方法清单
源码中的核心方法包括:addSpot。
| 方法类型 | 作用 | 示例 |
|---|---|---|
| 新增方法 | 创建记录 | ddMood、ddDish、ddLog |
| 行动方法 | 完成或触发动作 | stand、drink、 |
| echeck | ||
| 统计方法 | 计算总量或异常 | otal、bnormal、successDays |
| 卡片方法 | 渲染记录 | card |
| 辅助方法 | 最新记录或提醒 | latest、 |
| estNeeded |
5.2 新增记录
private addRecord(): void {
const text = this.draftText.trim();
if (text.length === 0) {
return;
}
this.records = [{ id: Date.now(), title: text, done: false }, ...this.records];
this.draftText = '';
}
5.3 动作反馈
private finishAction(id: number): void {
this.records = this.records.map((item: ChargeSpot) => {
return item.id === id ? { ...item, done: true } : item;
});
this.message = '已记录本次动作';
}
5.4 指标统计
private doneCount(): number {
return this.records.filter((item: ChargeSpot) => item.done).length;
}
六、Builder 卡片复用
6.1 Builder 清单
源码中的 Builder 组件包括:card。
@Builder
private card(item: ChargeSpot) {
Column() {
Text(item.title ?? item.name ?? '记录')
.fontSize(16)
.fontWeight(FontWeight.Bold)
}
.padding(14)
.backgroundColor('#FFFFFF')
.borderRadius(8)
}
6.2 复用价值
| 组件 | 作用 |
|---|---|
| card | 统一记录卡片 |
| 状态文本 | 呈现当前反馈 |
| 操作按钮 | 触发打卡或复查 |
| 列表区域 | 承载历史记录 |
6.3 分工边界
Builder 只描述 UI,业务判断留给 private 方法。这样可以避免卡片内部逻辑过重。
七、页面布局结构
7.1 基础布局
Scroll() {
Column() {
// 顶部状态
// 输入区域
// 操作按钮
// 历史卡片
}
.padding(16)
}
7.2 信息分区
| 区域 | 内容 | 价值 |
|---|---|---|
| 顶部状态 | 当前指标和建议 | 快速判断 |
| 输入区域 | 站点信息或记录值 | 完成记录 |
| 操作区域 | 打卡、复查、勾选 | 推进状态 |
| 卡片列表 | 历史和节点 | 支持复盘 |
| 反馈文案 | 消息提示 | 确认结果 |
7.3 列表渲染
ForEach(this.records, (item: ChargeSpot) => {
this.card(item)
}, (item: ChargeSpot) => item.id.toString())
八、交互链路
8.1 输入链路
TextInput({ text: this.draftText })
.onChange((value: string) => {
this.draftText = value;
})
8.2 按钮链路
Button('记录')
.onClick(() => {
this.addRecord();
})
8.3 反馈链路
private setMessage(text: string): void {
this.message = text;
}
实现重点:输入负责采集,方法负责处理,状态负责保存,UI 负责展示。四个职责不要混在一起。
九、出行场景表达策略
9.1 反馈层级
| 反馈类型 | 页面表达 |
|---|---|
| 当前状态 | 数值和标题 |
| 行动建议 | 文案提示 |
| 历史记录 | 卡片列表 |
| 异常提醒 | 高亮颜色 |
| 安全信息 | 联系人或离线标识 |
9.2 数据边界
出行数据需要基础校验。例如目标值不能为 0,指标不能为空,异常状态需要清楚说明。
9.3 隐私意识
周期、出行档案、体检指标等信息属于敏感数据,后续扩展时应加入本地保护或隐私锁。
十、运行与调试
10.1 DevEco Studio 运行
# 打开项目目录
# 同步依赖
# 运行 entry 模块
10.2 Hvigor 构建
hvigorw clean
hvigorw assembleHap
10.3 调试点
| 调试项 | 判断标准 |
|---|---|
| 输入状态 | 输入后字段是否变化 |
| 列表刷新 | 新记录是否出现 |
| 按钮动作 | 点击后状态是否推进 |
| 统计结果 | 数字是否与列表一致 |
| 反馈消息 | 操作后是否更新 |
十一、可维护性分析
11.1 文件规模
当前 Index.ets 约 61 行,属于轻量单页规模。继续扩展时可以拆分为输入组件、状态卡组件和记录列表组件。
11.2 状态收敛
能从列表计算的内容尽量使用方法派生,不要重复保存。
private recordCount(): number {
return this.records.length;
}
11.3 逻辑复用
新增、完成、统计、反馈等逻辑可以抽象为同类出行工具模板。
十二、扩展方向
12.1 本地存储
interface HealthStoreItem {
id: number;
type: string;
payload: string;
updatedAt: number;
}
12.2 通知提醒
护眼、午睡、口腔护理、站立办公、体检复查都适合接入提醒。
12.3 图表展示
步数、心情、饮食、出行指标可以扩展趋势图,提高复盘效率。
十三、同类模板抽象
13.1 数据模板
interface HealthItem {
id: number;
title: string;
done: boolean;
}
13.2 状态模板
@State items: HealthItem[] = [];
@State message: string = '';
13.3 卡片模板
@Builder
private healthCard(item: HealthItem) {
Row() {
Text(item.title).layoutWeight(1)
Text(item.done ? '已完成' : '待处理')
}
.padding(12)
}
十四、实现亮点
14.1 模型轻量
EV Charging Spots 使用 ChargeSpot 描述业务对象,既保持结构清晰,也避免过度设计。
14.2 状态明确
spots、name、price、idleText、selected 覆盖核心交互状态,页面刷新路径直接。
14.3 方法集中
addSpot 将业务动作集中到方法中,便于维护。
十五、总结
EV Charging Spots 是一个典型的鸿蒙 ArkTS 出行类小工具。它通过 ChargeSpot 建模业务对象,通过 spots、name、price、idleText、selected 管理页面状态,通过 addSpot 完成记录更新和状态反馈,再通过 card 渲染统一卡片。
这类项目的核心价值在于把一个出行场景做成闭环:记录入口明确,状态反馈及时,历史信息可复盘,后续可以自然扩展提醒、隐私保护、本地存储和图表展示。
如果这篇文章对你有帮助,欢迎点赞、收藏、关注,你的支持是我持续创作的动力!
相关资源:
更多推荐




所有评论(0)