鸿蒙 ArkTS 实战:Baking Club Orders 从烘焙社订单到兴趣社群工具完整解析
前言
Baking Club Orders 是一个围绕烘焙社群订单设计的鸿蒙 ArkTS 单页应用。
它把 展示订单数和试吃评分,维护作品、材料分工和活动日程 这类真实活动需求,拆成状态字段、输入组件、按钮动作和结果反馈。
本文基于项目真实的Index.ets源码展开,重点分析它如何用@State管理数据,如何用 ArkUI 组件组织页面,以及如何把一次兴趣活动变成可记录、可更新、可扩展的移动端工具。
图示说明:配图用于表达鸿蒙应用中状态、组件和交互反馈的关系,帮助理解本文的页面拆解思路。
可以结合 HarmonyOS 应用开发文档、ArkTS 语言基础、ArkUI 声明式开发范式、组件参考 等资料阅读本文。
兴趣社群类工具的关键不是功能越多越好,而是一次记录能否在当前页面里形成清楚的闭环。
一、项目定位与用户场景
1.1 业务场景
烘焙社订单 聚焦的场景是:展示订单数和试吃评分,维护作品、材料分工和活动日程。
这类场景通常发生在线下活动前后,用户需要快速打开页面,确认信息,修改内容,然后保存一条明确反馈。
1.2 目标读者
这篇文章适合想学习鸿蒙 ArkTS 小应用开发的读者,尤其适合关注兴趣社群工具、活动记录页面和状态驱动 UI的开发者。
1.3 页面价值
页面不追求复杂流程,而是让用户在一个屏幕内完成主要动作。
- 查看当前活动核心信息。
- 修改关键字段。
- 点击按钮触发状态变化。
- 从结果文字或数字中确认变化。
二、工程结构与入口组件
2.1 页面位置
项目核心代码位于入口页面。
entry/ src/ main/ ets/ pages/ Index.ets这种结构让文章分析可以直接围绕页面源码展开。
2.2 组件声明
@Entry@Componentstruct Index{build(){// 声明式 UI}}@Entry表示页面入口,@Component表示这是一个可渲染组件。
2.3 单页工具边界
当前项目没有引入多页面路由或远程接口,所有交互都围绕当前页面状态完成。
这让它非常适合作为 ArkTS 实战学习案例。
三、状态模型设计
3.1 状态字段总览
| 状态字段 | 初始值 | 页面职责 |
|---|---|---|
work | Lemon cake | 烘焙作品 |
materials | Flour: Lin, lemon: Tao | 材料分工 |
score | 86 | 试吃评分 |
dateText | Saturday tasting | 活动日程 |
orders | 9 | 订单数 |
这些字段共同构成了 烘焙社订单 的业务模型。
3.2 状态命名的直观性
字段名都直接指向页面语义。
例如work是主记录字段,orders是结果或计数字段。
这种命名让源码可读性很高。
3.3 核心状态与函数源码
@Statework:string='Lemon cake';@Statematerials:string='Flour: Lin, lemon: Tao';@Statescore:number=86;@StatedateText:string='Saturday tasting';@Stateorders:number=9;join():void{this.orders++;this.score+=1;}这段代码展示了项目最重要的状态和交互函数。
状态变化后,页面中引用这些状态的组件会随之刷新。
四、交互逻辑拆解
4.1 交互表
| 交互点 | 源码行为 | 用户看到的结果 |
|---|---|---|
join | orders 自增,score 同步加一 | 当前页面即时刷新 |
Baking work | 维护作品名称 | 当前页面即时刷新 |
Material assignment | 维护材料责任人 | 当前页面即时刷新 |
每个交互都对应一个明确的业务动作。
4.2 输入同步
项目通过TextInput的onChange回调同步输入。
TextInput({text:this.work,placeholder:'烘焙作品'}).onChange((v:string)=>this.work=v)这种写法直接、轻量,适合字段数量不多的活动页面。
4.3 按钮动作
按钮通常只做一件事:修改状态。
Button('Save').width('100%').onClick(()=>{this.orders=this.work;})动作越短,用户越容易理解。
五、布局结构分析
5.1 页面布局概览
顶部棕色统计区并列显示订单数和评分,正文表单维护作品、材料和活动日程。
这个布局把主信息放在更显眼的位置,把编辑区放在下方或右侧。
5.2 关键 UI 片段
Row(){Column(){Text('Orders').fontSize(16).fontColor('#FEF3C7')Text(this.orders.toString()).fontSize(56).fontWeight(FontWeight.Bold).fontColor('#FFFFFF')}.layoutWeight(1).alignItems(HorizontalAlign.Center)Column(){Text('Taste').fontSize(16).fontColor('#FEF3C7')Text(this.score.toString()).fontSize(56).fontWeight(FontWeight.Bold).fontColor('#FFFFFF')}.layoutWeight(1).alignItems(HorizontalAlign.Center)}.height('34%').width('100%').backgroundColor('#92400E')这段 UI 代码体现了项目的主要视觉结构。
5.3 滚动容器的作用
活动记录类页面经常包含多个输入框。
Scroll(){Column({space:16}){// 活动内容}.padding(20).width('100%')}滚动容器可以保证小屏设备上也能完整操作。
六、视觉层级与主题色
6.1 当前配色
当前页面背景色是#FFFBEB,强调色是#92400E。
颜色被用来区分主信息和辅助信息,而不是单纯装饰。
6.2 字号层级
| 层级 | 常见字号 | 用途 |
|---|---|---|
| 主标题 | 30 左右 | 页面主题 |
| 强指标 | 54 到 56 | 数量、评分、进度 |
| 内容文本 | 15 到 24 | 输入结果和说明 |
6.3 卡片留白
项目中大量使用padding和borderRadius。
Text('Info').padding(16).backgroundColor('#92400E').borderRadius(8)这能让活动信息更容易扫读。
七、数据计算与边界
7.1 数字自增
项目中有照片数、录音数、点评数、观察次数、保存次数、进度、订单、评分、玩家数和投票数等数字状态。
this.count++;自增逻辑要保持结果可见,否则用户无法确认动作是否生效。
7.2 上限控制
当字段有自然上限时,应使用Math.min。
this.progress=Math.min(100,this.progress+10);this.rating=Math.min(100,this.rating+1);这能避免进度或评分超过业务范围。
7.3 数字输入转换
费用、人均等场景需要从字符串转数字。
consttotal=Number(this.cost);constsplit=Math.round(total/this.players);真实项目中还可以补充空值和非法值处理。
八、活动记录类应用的体验原则
8.1 首屏直接给答案
用户打开 Baking Club Orders 时,应该立刻看到最关键的活动信息。
例如主题、数量、进度、评分、地点或当前记录。
8.2 操作入口要明确
按钮文案应该短而直接。
- 保存记录。
- 增加数量。
- 生成分配。
- 投票或签到。
- 推进步骤。
这些动作都能在当前页面完成。
8.3 反馈文字要具体
反馈不应该只写“成功”。
更好的方式是把用户刚刚编辑的字段带入结果。
this.message=this.work+' updated';九、组件映射
9.1 常用组件
| 组件 | 项目用途 | 特点 |
|---|---|---|
Text | 展示标题、状态和结果 | 轻量 |
TextInput | 编辑活动字段 | 直接 |
Button | 触发状态变化 | 明确 |
Row | 并列展示指标 | 适合统计 |
Grid | 四宫格展示信息 | 适合卡片 |
Scroll | 承载多输入内容 | 适合小屏 |
9.2 布局组合
项目根据场景选择不同布局。
有的页面使用四宫格,有的页面使用左右分栏,有的页面使用顶部大色块。
这种差异让每个应用都有自己的使用节奏。
9.3 信息密度
兴趣活动工具要保持适中信息密度。
太少会像便签,太多会像表格系统。
当前项目选择了单页工具的中间状态。
十、可扩展数据模型
10.1 抽象记录对象
interfaceClubRecord{id:string;title:string;detail:string;count:number;updatedAt:number;}这个对象可以承载历史记录。
10.2 数组状态
@Staterecords:ClubRecord[]=[];数组状态适合把当前单条记录扩展为列表。
10.3 追加记录
this.records=[...this.records,{id:Date.now().toString(),title:this.work,detail:this.orders,count:1,updatedAt:Date.now()}];不可变追加方式更利于 UI 刷新。
十一、持久化方向
11.1 保存当前状态
活动工具一旦真实使用,就需要保存上一次记录。
interfaceSavedClubState{currentTitle:string;currentDetail:string;records:ClubRecord[];version:number;}11.2 恢复默认值
functionfallbackText(value:string|undefined):string{returnvalue||'';}读取旧数据时要考虑字段缺失。
11.3 数据升级
加入version后,后续字段扩展更稳。
例如新增标签、地点坐标或附件信息时,可以按版本迁移。
十二、调试与验证
12.1 验证状态变化
Button('Debug').onClick(()=>{console.info('value: '+this.work);})先确认状态变化,再看 UI 是否刷新。
12.2 验证布局适配
在小屏设备上重点看三个点。
- 卡片文字是否过长。
- 输入框是否完整可见。
- 按钮是否被挤出屏幕。
12.3 验证数字边界
| 场景 | 风险 | 处理 |
|---|---|---|
| 自增过快 | 数字超出预期 | 设置上限或业务条件 |
| 空字符串转数字 | 出现异常结果 | 使用默认值 |
| 长文本输入 | 卡片被撑开 | 使用滚动容器 |
| 多字段同时变化 | 反馈不清楚 | 结果文案复述关键字段 |
十三、工程化拆分
13.1 抽离卡片组件
@BuilderfunctionInfoCard(label:string,value:string,color:string){Column({space:6}){Text(label).fontSize(14).fontColor('#6B7280')Text(value).fontSize(18).fontWeight(FontWeight.Bold)}.padding(16).backgroundColor(color).borderRadius(8)}卡片组件可以复用到统计、状态、活动摘要等区域。
13.2 抽离格式化函数
exportfunctionbuildMessage(title:string,detail:string):string{returntitle+' / '+detail;}格式化函数独立后,页面组件会更清爽。
13.3 抽离主题
constTheme={pageBg:'#FFFBEB',accent:'#92400E',radius:8};统一主题方便继续扩展多个页面。
十四、同类应用对比
14.1 单页工具
单页工具适合快速记录和即时反馈。
Baking Club Orders 当前就属于这种形态。
14.2 多记录工具
当记录量增加后,可以加入历史列表。
interfaceRecordGroup{date:string;items:ClubRecord[];}14.3 社群协作工具
如果加入多人协作,可以扩展成员、角色、报名和消息提醒。
但当前版本已经具备最小可用闭环。
十五、发布级技术亮点
15.1 代码短但语义完整
烘焙社订单 的字段和按钮都能直接对应业务场景。
这让读者可以从页面代码理解产品设计。
15.2 反馈即时
每次点击都会改变一个可见状态。
这对移动端工具很关键。
15.3 扩展路径清晰
当前项目可以继续扩展历史记录、本地存储、附件、标签和统计图。
先完成一个可用单页,再扩展为完整社群工具,是这类鸿蒙应用更自然的演进方式。
十六、总结
Baking Club Orders 用 ArkTS 和 ArkUI 展示了一个 烘焙社群订单 场景如何落成可运行页面。
它通过@State保存核心数据,通过TextInput接收用户输入,通过Button修改状态,再用卡片、文字和数字反馈结果。
从技术学习看,它覆盖了状态管理、声明式布局、输入同步、按钮事件、条件计算和移动端适配。
从产品场景看,烘焙社订单 把 展示订单数和试吃评分,维护作品、材料分工和活动日程 这件事变得更轻、更清晰,也更适合在手机端随手维护。
相关资源:
- HarmonyOS 应用开发文档
- ArkTS 语言基础
- ArkUI 声明式开发范式