鸿蒙 ArkTS 实战:Print Copy Booking 从打印复印预约到打印服务应用完整解析
鸿蒙 ArkTS 实战:Print Copy Booking 从打印复印预约到打印服务应用完整解析
前言
打印复印预约 是一个典型的鸿蒙 ArkTS 小型业务应用,页面体量不大,但覆盖了状态驱动界面、列表渲染、条件文案、按钮事件和业务数据即时反馈这些移动端开发中最常见的能力。
这篇文章围绕 Print Copy Booking 的真实项目内容展开,重点分析它如何把“打印店为 PDF 合同登记份数、彩印开关、A4 单双面与装订规格,并即时计算取件费用。”落成一个可交互页面。
小型业务应用的价值不在于页面数量,而在于是否把状态、数据和用户动作串成稳定闭环。
图示说明:本文以项目中的 ArkTS 页面为基础,将界面拆成顶部信息、业务选择、详情反馈和动作按钮四层。
一、项目定位与业务场景
1.1 应用解决的问题
打印店为 PDF 合同登记份数、彩印开关、A4 单双面与装订规格,并即时计算取件费用。
这个场景非常适合用鸿蒙声明式 UI 来实现,因为页面状态集中、业务反馈明确、用户动作路径短。
1.2 页面面向的用户
主要用户包括三类:
- 需要快速登记服务信息的一线工作人员。
- 需要查看当前状态和费用变化的服务对象。
- 需要复用轻量业务页面结构的 ArkTS 开发者。
1.3 核心业务对象
| 对象 | 在页面中的作用 | 技术承载 |
|---|---|---|
| 当前选择 | 决定高亮卡片和详情内容 | @State |
| 业务数组 | 提供列表、标签或流程节点 | string[] / number[] |
| 操作按钮 | 推动状态变化 | onClick / onChange |
| 反馈区域 | 展示当前结果 | Text / Row / Column |
二、源码结构与页面入口
2.1 页面文件位置
该应用的主要页面位于 entry 模块的 pages 目录,核心逻辑集中在 Index 页面中。对于这种单页工具,将展示、状态和事件放在同一个组件中,便于阅读和调试。
@Entry@Componentstruct Index{build(){Column(){Text('打印复印预约')}}}2.2 组件职责拆分
| 区域 | 职责 | 典型组件 |
|---|---|---|
| 顶部标题区 | 显示业务主题和摘要信息 | Row、Column、Text |
| 选择区 | 切换套餐、科目、节点或物品 | ForEach、Grid、Toggle |
| 详情区 | 展示当前选择后的解释 | Text、Stack |
| 操作区 | 完成确认、追加、计费等动作 | Button |
2.3 为什么适合单组件实现
打印复印预约 的业务状态只有 2 个主要字段:copies、color。状态数量少,跨页面共享需求不强,采用单组件实现可以降低样板代码,让读者把注意力放在 ArkTS 状态绑定本身。
三、状态建模
3.1 State 字段说明
| 字段 | 类型 | 说明 |
|---|---|---|
| copies | number | 打印份数,默认 6 份 |
| color | boolean | 是否彩印 |
这些字段都直接参与 UI 渲染,只要值发生变化,相关 Text、颜色、按钮文案或费用结果就会自动刷新。
3.2 状态声明代码
@Entry@Componentstruct Index{@Statecopies:number=6;// 打印份数,默认 6 份@Statecolor:boolean=false;// 是否彩印}3.3 状态粒度控制
状态字段保持简短有两个好处:
- 页面变化来源清楚,排查问题时可以直接定位到对应字段。
- 渲染表达式更直观,不需要在多个对象之间频繁跳转。
- 后续扩展持久化时,可以把这些字段直接映射到缓存或服务端参数。
对小工具而言,状态字段越贴近用户动作,页面越容易维护。
四、业务数据数组设计
4.1 数组内容
specs:A4 单面、A4 双面、装订
项目中没有把所有展示内容写死在多个 Text 里,而是通过数组配合 ForEach 渲染。这种方式让选项增加、顺序调整和文案替换都更自然。
4.2 数组渲染示例
ForEach(this.items,(item:string,index:number)=>{Text(item).fontSize(16).fontWeight(FontWeight.Bold).onClick(()=>{this.current=index})})4.3 数据与索引绑定
当状态字段保存的是索引时,页面可以用items[current]取得当前内容,也可以用index === current判断是否高亮。
Text(this.items[this.current]).fontColor(this.current===index?'#FFFFFF':'#0284C7')这种写法在 打印复印预约 中非常常见,既能表达当前选择,也能减少额外对象结构。
五、界面布局实现
5.1 主布局思路
页面以 Column 或 Row 作为主容器,根据业务主题选择不同的信息密度。打印复印预约 的布局重点是让用户第一眼看到当前状态,再完成一次明确操作。
Column(){this.Header()this.BusinessArea()this.ActionArea()}.width('100%').height('100%').backgroundColor('#FFFFFF')5.2 视觉层次
| 层级 | 设计目标 | 实现方式 |
|---|---|---|
| 一级信息 | 告诉用户当前是什么业务 | 大字号标题 |
| 二级信息 | 展示对象、时间、备注 | 中性灰色 Text |
| 关键状态 | 突出选择、金额、阶段 | 主题色与加粗 |
| 操作按钮 | 推动状态变化 | Button 绑定事件 |
5.3 主题色使用
该项目使用#0284C7作为业务主色。主题色主要出现在按钮、高亮卡片、流程节点或重要金额上,避免把所有文本都涂成同一种颜色。
Text('当前状态').fontSize(18).fontWeight(FontWeight.Bold).fontColor('#0284C7')六、交互行为解析
6.1 用户动作列表
- 切换 Toggle 更新 color
- 点击 +1 增加 copies
- 费用按黑白/彩印单价实时计算
6.2 事件绑定代码
Toggle({type:ToggleType.Switch,isOn:this.color}).onChange((on:boolean)=>{this.color=on})Text('费用统计:¥'+String(this.copies*(this.color?3:1)))6.3 交互反馈闭环
- 切换 Toggle 更新 color
- 点击 +1 增加 copies
- 费用按黑白/彩印单价实时计算
这些动作都不会跳转页面,而是在当前页面即时反馈结果。对于服务登记类应用,这种即时反馈可以减少误操作,也能让用户清楚地知道操作是否生效。
七、关键业务计算
7.1 计算表达式
本项目最核心的业务表达式可以概括为:
fee=copies*(color?3:1)7.2 为什么直接在页面展示计算结果
打印复印预约 属于轻量业务工具,计算逻辑短、依赖字段少,把计算结果直接展示在页面中可以减少额外方法和中间状态。
7.3 可扩展计算封装
如果后续加入更多规则,可以把计算封装成方法:
privategetDisplayResult():string{constvalue='fee = copies * (color ? 3 : 1)'returnString(value)}在真实业务中,费用、阶段和状态文本通常会继续扩展,因此保留清晰的计算入口很重要。
八、ArkTS 组件细节
8.1 Text 的信息表达
Text 在页面中承担标题、说明、状态和金额展示。不同字号和颜色让用户自然区分内容优先级。
Text('打印复印预约').fontSize(26).fontWeight(FontWeight.Bold).fontColor('#0284C7')8.2 Button 的动作表达
Button 只绑定一个清晰动作,不在一次点击中混入过多业务副作用。
Button('确认').backgroundColor('#0284C7').onClick(()=>{// 更新当前页面状态})8.3 条件样式
条件样式让选中态更明显:
.backgroundColor(this.current===index?'#0284C7':'#FFFFFF').fontColor(this.current===index?'#FFFFFF':'#111827')8.4 列表循环
ForEach 适合处理选项、流程和服务清单:
ForEach(this.items,(item:string,index:number)=>{Row(){Text(item)Text(String(index+1))}})九、页面可维护性
9.1 命名可读性
copies、color 这些字段都与业务动作直接对应,阅读源码时可以快速判断每个字段控制哪一块页面。
9.2 数据集中管理
数组字段统一放在组件顶部,避免在 build 中散落大量重复文案。
privateitems:string[]=['选项一','选项二','选项三']9.3 样式边界
当前项目直接链式调用样式方法,适合页面较短的场景。如果页面继续增长,可以按区域拆成 builder 方法。
@BuilderprivateSectionTitle(title:string){Text(title).fontSize(18).fontWeight(FontWeight.Bold)}十、调试与验证
10.1 状态变化验证
调试时可以按以下顺序确认:
- 初始状态是否与默认 UI 一致。
- 点击选项后高亮是否移动。
- 按钮点击后数字、状态或文案是否刷新。
- 边界条件是否保持稳定。
10.2 日志辅助
Button('调试动作').onClick(()=>{console.info('current state changed')})10.3 常见问题定位
| 问题 | 可能原因 | 处理方式 |
|---|---|---|
| 点击后无变化 | 修改的不是 @State 字段 | 确认字段声明位置 |
| 高亮错位 | index 与数组顺序不一致 | 检查 ForEach 数据源 |
| 文案异常 | 条件表达式分支错误 | 单独验证布尔值 |
| 费用不更新 | 表达式未依赖状态 | 检查 copies、fee 等字段 |
十一、同类业务扩展
11.1 接入本地缓存
可以把当前选择和操作结果保存到 Preferences,让页面重启后恢复上次状态。
interfaceSavedState{current:numberupdatedAt:string}11.2 接入远端接口
如果 打印复印预约 需要和后台系统同步,可以把页面状态作为请求参数:
{"business":"打印复印预约","selected":1,"status":"confirmed"}11.3 表单化改造
业务字段继续增加时,可以把顶部信息、选项列表和备注区域拆成更细的组件,形成可复用的服务登记模板。
十二、性能与体验细节
12.1 减少不必要状态
只有会影响界面的字段才需要使用 @State。静态数组使用 private 字段即可,避免把每个展示文本都变成响应式数据。
12.2 保持点击目标清晰
按钮、卡片和标签都要有足够 padding,尤其是服务预约类页面经常在门店或外勤场景中使用,点击目标太小会影响效率。
12.3 色彩反馈一致
同一业务动作使用同一主题色#0284C7,可以帮助用户把“可操作区域”和“当前结果”联系起来。
十三、完整实现片段
13.1 页面骨架
@Entry@Componentstruct Index{@Statecopies:number;@Statecolor:boolean;build(){Column(){Text('打印复印预约')Text('业务主题:打印服务')}}}13.2 业务配置
// specs:A4 单面、A4 双面、装订privateprimaryColor:string='#0284C7'13.3 事件处理
Toggle({type:ToggleType.Switch,isOn:this.color}).onChange((on:boolean)=>{this.color=on})Text('费用统计:¥'+String(this.copies*(this.color?3:1)))13.4 结果展示
Text('当前业务结果').fontSize(20).fontWeight(FontWeight.Bold).fontColor('#0284C7')十四、技术讲解要点
14.1 技术亮点
- 使用 ArkTS 声明式语法组织单页业务。
- 使用 @State 驱动用户选择和结果反馈。
- 使用 ForEach 渲染业务数组,减少重复代码。
- 使用条件样式表达选中态、阶段态和完成态。
14.2 业务亮点
- 打印店为 PDF 合同登记份数、彩印开关、A4 单双面与装订规格,并即时计算取件费用。
- 页面路径短,用户可以在一个屏幕内完成主要动作。
- 关键字段有即时反馈,适合真实服务登记场景。
14.3 可复用价值
打印复印预约 的结构可以迁移到更多生活服务、社区服务、教育预约和门店登记类应用中。只要替换数组内容、状态字段和按钮动作,就能形成新的业务页面。
十五、学习路线
15.1 初学者关注点
先理解 @State 与 UI 刷新的关系,再观察 ForEach 如何把数组变成可点击列表。
15.2 进阶开发者关注点
重点关注状态字段是否足够少、事件逻辑是否可预测、业务计算是否能被独立测试。
15.3 工程化关注点
当页面进入多人维护阶段,可以把配置、样式、组件和服务请求拆分出来,形成更清晰的工程边界。
总结
Print Copy Booking 展示了鸿蒙 ArkTS 在轻量业务应用中的实用价值。它用少量状态字段承载 打印服务 场景,用数组渲染减少重复 UI,用按钮事件完成业务推进,并通过条件样式让用户立即感知当前结果。
从工程角度看,打印复印预约 的重点不是复杂算法,而是把真实业务动作翻译成稳定的界面状态。这种能力对于服务预约、订单登记、社区管理和本地生活工具都非常关键。
相关链接:
- HarmonyOS 应用开发指南
- ArkTS 快速入门
- ArkUI 声明式开发
