鸿蒙 ArkTS 实战:Curtain Measure Booking 从窗帘量尺预约到家装量尺应用完整解析

前言

窗帘量尺预约 是一个贴近生活服务场景的鸿蒙 ArkTS 单页应用。它的源码并不复杂,却把状态驱动界面列表循环渲染条件样式按钮事件业务结果即时反馈都放在了一个很清楚的页面里。

本文围绕 Curtain Measure Booking 的真实页面内容展开,分析它如何把“窗帘门店为客厅、主卧、书房记录宽度和高度,展示面料选择、报价单和安装进度。”实现成可交互、可扩展、可复用的鸿蒙应用页面。

做生活服务类工具时,最重要的不是堆功能,而是让用户在一次点击后马上看到业务状态变化。

在这里插入图片描述

图示说明:本文拆解的页面包含业务标题区、服务数据区、状态反馈区和操作按钮区,适合用来学习 ArkTS 单页业务建模。

一、业务背景与页面目标

1.1 场景背景

窗帘门店为客厅、主卧、书房记录宽度和高度,展示面料选择、报价单和安装进度。

这类应用通常出现在社区服务、门店登记、上门服务、本地生活和轻量办公场景中。用户不会长时间停留研究界面,而是希望快速确认状态、费用、进度或当前选项。

1.2 页面目标

页面目标可以拆成三点:

  1. 清楚展示当前业务对象和核心信息。
  2. 让用户通过点击完成选择、推进或确认。
  3. 在当前页面实时反馈业务结果。

1.3 技术关注点

关注点 项目体现 技术方式
状态变化 room、install @State
数据选项 rooms:客厅、主卧、书房;widthList:320、260、180 private 数组
点击交互 按钮、卡片、条目 onClick / onChange
视觉反馈 高亮、进度、金额 条件样式

二、项目入口与源码结构

2.1 页面入口

该项目的主要业务集中在 Index 页面中,使用 @Entry 标记入口组件,使用 @Component 描述可渲染结构。单页应用的好处是路径短,适合集中讲清业务闭环。

@Entry
@Component
struct Index {
  build() {
    Column() {
      Text('窗帘量尺预约')
    }
  }
}

2.2 单页结构优势

对于 窗帘量尺预约 这种业务规模,单页结构有三个优势:

  • 状态来源集中,点击后变化容易追踪。
  • 业务数组靠近渲染逻辑,维护成本低。
  • 调试时可以直接观察页面刷新结果。

2.3 页面模块拆解

模块 作用 典型组件
标题区域 显示业务名称和摘要 Row、Column、Text
选项区域 展示任务、流程或服务项 ForEach、Grid、Stack
反馈区域 显示费用、进度或状态 Text、Circle、Rect
操作区域 完成确认或推进 Button、Toggle

三、状态建模

3.1 State 字段表

字段 类型 业务含义
room number 当前房间索引
install number 安装进度步骤,默认第 1 步

这些字段全部参与界面渲染,只要字段更新,相关文案、颜色、按钮状态或计算结果就会同步变化。

3.2 状态声明代码

@Entry
@Component
struct Index {
  @State room: number = 0; // 当前房间索引
  @State install: number = 1; // 安装进度步骤,默认第 1 步
}

3.3 状态粒度设计

窗帘量尺预约 的状态字段数量较少,说明页面没有过度建模。它把真正会变化的内容交给 @State,把静态选项保留为 private 数组。

@State 应该服务于界面变化,而不是替代所有普通字段。

四、业务数据数组

4.1 数组内容

rooms:客厅、主卧、书房;widthList:320、260、180

数组让页面可以通过循环渲染多个业务选项,避免重复写很多结构相似的 Text、Row 或 GridItem。

4.2 ForEach 渲染方式

ForEach(this.items, (item: string, index: number) => {
  Text(item)
    .fontSize(16)
    .fontWeight(FontWeight.Bold)
    .onClick(() => {
      this.current = index
    })
})

4.3 索引绑定的价值

当前项目大量使用索引来表示“选中哪一项”或“推进到哪一步”。这种方式适合选项数量固定、展示顺序稳定的页面。

Text(this.items[this.current])
  .fontColor(this.current === index ? '#FFFFFF' : '#4F46E5')

五、页面布局设计

5.1 主容器组织

页面主容器通常由 Column 或 Row 构成。窗帘量尺预约 的布局重点是先给出业务主题,再让用户看到可操作区域,最后展示结果。

Column() {
  Text('窗帘量尺预约')
  Blank()
  Button('确认')
}
.width('100%')
.height('100%')
.backgroundColor('#FFFFFF')

5.2 信息层级

层级 展示内容 设计目标
一级 标题、业务对象 快速识别页面用途
二级 时间、备注、说明 补充业务上下文
三级 费用、进度、状态 强化当前结果
操作 确认、推进、新增 完成业务动作

5.3 主题色策略

项目使用 #4F46E5 作为主色,常出现在按钮、高亮项和核心数字上。这种颜色策略能让用户快速找到当前可操作区域。

Button('主要操作')
  .backgroundColor('#4F46E5')

六、交互行为解析

6.1 主要动作

  1. 点击房间列表切换 room
  2. 尺寸读取 widthList[room]
  3. 推进安装按钮让 install 增加 1

6.2 项目中的事件代码

Text('报价单:¥' + String(this.widthList[this.room] * 3))
Button('推进安装').onClick(() => { this.install += 1 })

6.3 交互闭环

  • 点击房间列表切换 room
  • 尺寸读取 widthList[room]
  • 推进安装按钮让 install 增加 1

点击动作与页面反馈绑定在同一个状态字段上,因此用户不需要跳转页面,也能立即知道业务是否推进成功。

七、核心业务计算

7.1 计算表达式

quote = widthList[room] * 3

7.2 计算结果展示

在 窗帘量尺预约 中,计算结果通常直接出现在 Text 组件中,比如进度、费用、数量或状态文案。

Text('当前结果:' + String(result))
  .fontSize(22)
  .fontWeight(FontWeight.Bold)
  .fontColor('#4F46E5')

7.3 封装为方法

如果后续业务规则变多,可以将计算封装为方法:

private getResultText(): string {
  return String('quote = widthList[room] * 3')
}

这样可以让 build 方法更短,也方便单独调整业务规则。

八、ArkTS 组件使用细节

8.1 Text 组件

Text 用来表达标题、说明、状态、金额和备注。字体大小和颜色变化,是生活服务类页面里最基础的视觉层级。

Text('窗帘量尺预约')
  .fontSize(26)
  .fontWeight(FontWeight.Bold)
  .fontColor('#4F46E5')

8.2 Button 组件

Button 承载明确动作,例如确认、推进、新增、记录费用等。一个按钮最好对应一个清楚的业务变化。

Button('推进')
  .backgroundColor('#4F46E5')
  .onClick(() => {
    this.current += 1
  })

8.3 条件样式

条件样式让用户知道当前选中项、完成项或待处理项。

.backgroundColor(this.current === index ? '#4F46E5' : '#FFFFFF')
.fontColor(this.current === index ? '#FFFFFF' : '#111827')

8.4 Stack 与图形组件

部分页面使用 Stack、Circle、Rect 组织视觉区域。它们适合表达照片区域、进度节点、仪表盘或业务卡片。

Stack() {
  Rect().width('100%').height(220).fill('#F8FAFC')
  Text('业务信息')
}

九、可维护性分析

9.1 字段命名

room、install 都是直接对应业务含义的字段,阅读源码时不需要额外猜测它们控制哪一块界面。

9.2 静态数据管理

静态数组靠近组件顶部,后续新增条目时只需要改数组,不需要复制整段 UI。

private items: string[] = ['选项一', '选项二', '选项三']

9.3 组件拆分时机

当页面扩展到多个区域都需要复用样式时,可以拆出 builder 方法。

@Builder
private Tag(text: string, selected: boolean) {
  Text(text)
    .fontColor(selected ? '#FFFFFF' : '#4F46E5')
}

十、调试与验证

10.1 操作路径验证

调试 窗帘量尺预约 时,可以按真实业务动作验证:

  1. 打开页面后初始状态是否正确。
  2. 点击列表、卡片或按钮后,状态是否变化。
  3. 费用、进度或状态文案是否同步刷新。
  4. 边界条件是否不会越界。

10.2 日志定位

Button('调试')
  .onClick(() => {
    console.info('state changed')
  })

10.3 常见问题表

问题 可能原因 处理方式
点击后没有变化 字段不是 @State 将变化字段声明为 @State
高亮位置不对 index 与状态值不匹配 检查 ForEach 顺序
文案不刷新 表达式没有依赖状态 让 Text 读取状态字段
数字越界 递增缺少限制 增加 if 判断

十一、扩展方向

11.1 增加本地缓存

对于 家装量尺 场景,可以保存最近一次选择和业务结果,让用户下次打开时继续处理。

interface LocalSnapshot {
  selected: number
  updatedAt: string
}

11.2 增加接口同步

当应用接入后台系统时,可以把状态字段转换为请求参数。

{
  "page": "窗帘量尺预约",
  "state": "room、install",
  "scene": "家装量尺"
}

11.3 增加角色权限

生活服务类应用常见多个角色:用户、服务人员、管理员。后续可以基于角色控制按钮是否可见。

十二、体验优化

12.1 点击区域

服务登记类页面常在移动场景下使用,按钮和卡片的 padding 要足够,避免误触。

12.2 反馈清晰

每次状态变化后,页面应该立刻有视觉反馈:颜色变化、数字变化、状态文案变化至少要有一种。

12.3 边界控制

对于递增、推进、完成类操作,需要限制最大值。

if (this.current < max) {
  this.current += 1
}

十三、完整实现片段

13.1 页面骨架

@Entry
@Component
struct Index {
  @State room: number = 0;
  @State install: number = 1;

  build() {
    Column() {
      Text('窗帘量尺预约')
      Text('业务类型:家装量尺')
    }
  }
}

13.2 数据声明

// rooms:客厅、主卧、书房;widthList:320、260、180
private primaryColor: string = '#4F46E5'

13.3 事件处理

Text('报价单:¥' + String(this.widthList[this.room] * 3))
Button('推进安装').onClick(() => { this.install += 1 })

13.4 状态展示

Text('状态已更新')
  .fontSize(18)
  .fontWeight(FontWeight.Bold)
  .fontColor('#4F46E5')

十四、同类页面复用

14.1 可复用结构

窗帘量尺预约 的页面结构可以迁移到很多同类场景:先定义业务数组,再定义当前状态,最后通过按钮推进。

14.2 可复用逻辑

  • 选项列表通过 ForEach 渲染。
  • 当前项通过 number 状态保存。
  • 布尔状态用于确认、完成、收款等二值场景。
  • 费用或进度通过表达式计算。

14.3 可复用样式

主题色、卡片圆角、间距和文字层级可以抽成公共常量,让多个页面保持一致。

十五、工程价值

15.1 对初学者的价值

这个项目适合练习 ArkTS 的基础语法、声明式 UI、状态刷新和事件绑定。

15.2 对业务开发的价值

它证明了轻量页面也需要清晰建模。只要状态字段设计合理,小页面同样能表达完整业务流程。

15.3 对后续扩展的价值

后续可以加入数据持久化、远端接口、权限控制、订单编号、服务评价和历史记录,让 窗帘量尺预约 从演示页面升级为真实工具。

总结

Curtain Measure Booking 通过简洁的 ArkTS 代码完成了 家装量尺 场景的核心交互。页面围绕 room、install 建立状态模型,围绕 rooms:客厅、主卧、书房;widthList:320、260、180 组织业务数据,再通过按钮和条件样式完成即时反馈。

从这个项目可以看到,鸿蒙 ArkTS 做轻量生活服务应用非常直接:状态定义清楚,数组渲染稳定,交互动作单一,页面反馈及时,就能支撑一个可读、可维护、可扩展的业务页面。


相关链接:

Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐