步骤引导(Stepper)是现代应用中处理复杂流程的标准 UI 模式。从项目创建向导到电商结账流程,从新用户注册到任务引导——将复杂操作分解为多个有序步骤,每一步聚焦一个子任务,能显著降低用户的认知负担和操作出错率。

HarmonyOS NEXT ArkUI 虽然没有内置的 Stepper 组件,但通过基础组件的组合(进度指示器、条件渲染、导航按钮),可以构建出功能完整的步骤引导系统。本文将深入讲解步骤引导的设计模式,并通过一个"项目创建向导"实战案例展示步骤导航、进度追踪、快速跳转和完成反馈等功能。

关键词:HarmonyOS、ArkUI、Stepper、步骤引导、进度导航、分步流程

一、步骤引导模式的设计原理

1.1 为什么要分步

面对一个包含 10+ 输入项的表单,用户的第一反应通常是"好麻烦"。心理学上的"选择过载"(Choice Overload)效应告诉我们:一次性呈现过多选项会降低决策质量和完成意愿。

分步引导将 10 个输入项分成 4 步(每步 2-3 项),用户在每一步只需关注少量信息,完成一步后再进入下一步。这种"渐进式信息披露"(Progressive Disclosure)策略显著提升了完成率——研究表明,分步表单的完成率比单页表单高约 20-30%。

1.2 Stepper 的核心元素

一个标准的步骤引导包含四个元素:

  1. 进度指示器(Progress Indicator):可视化当前进度,告知用户"你在哪里、还剩多少"
  2. 步骤内容区(Step Content):当前步骤的具体输入/操作区域
  3. 导航按钮(Navigation):上一步 / 下一步 / 提交
  4. 完成状态(Completion State):所有步骤完成后的成功反馈

这四个元素在 ArkUI 中分别对应:Row + 条件渲染、Column + 条件渲染、Button + onClick、条件渲染的完成页。

二、进度指示器

2.1 步骤圆点 + 连接线

进度指示器是 Stepper 最核心的视觉元素。我们使用带编号的圆点 + 连接线实现:

Row() {
  ForEach(this.steps, (step: StepItem, idx: number) => {
    // 步骤圆点
    Column() {
      if (idx < this.currentStep) {
        Text('✓')  // 已完成 → 对勾
          .fontSize(14).fontColor('#FFFFFF').fontWeight(FontWeight.Bold)
      } else {
        Text((idx + 1).toString())  // 当前或未完成 → 数字
          .fontSize(13)
          .fontColor(idx === this.currentStep ? '#FFFFFF' : '#9999AA')
          .fontWeight(idx === this.currentStep ? FontWeight.Bold : FontWeight.Normal)
      }
    }
    .width(28).height(28)
    .justifyContent(FlexAlign.Center).borderRadius(14)
    .backgroundColor(
      idx < this.currentStep ? step.color :          // 已完成 → 主题色
      idx === this.currentStep ? step.color :         // 当前 → 主题色
      '#F2F3F5'                                        // 未完成 → 灰色
    )

    // 连接线(最后一个步骤后不加)
    if (idx < this.steps.length - 1) {
      Row()
        .width(24).height(2)
        .backgroundColor(idx < this.currentStep ? step.color : '#E8E8E8')
    }
  })
}

圆点的三种状态:

  • 已完成(idx < currentStep):显示 ✓,背景为主题色
  • 进行中(idx === currentStep):显示编号,背景为主题色,外层有光晕(border)
  • 待完成(idx > currentStep):显示编号,背景为灰色,文字为灰色

连接线的两种状态:

  • 已完成(前一步已完成):显示主题色实线
  • 待完成(前一步未完成):显示灰色线

2.2 点击跳转

每个步骤圆点都可以点击,直接跳转到对应步骤:

.onClick(() => { this.goToStep(idx); })

这允许用户在已完成和当前步骤之间自由导航。待完成步骤(idx > currentStep)不可跳转——这是一个常见的设计约束,确保用户按顺序完成每一步。

如果想支持"任意顺序跳转",可以移除这个限制。但通常建议强制顺序,因为后续步骤的选项可能依赖前面步骤的选择。
在这里插入图片描述

三、步骤内容与导航

3.1 条件渲染

当前步骤的内容通过 currentStep 状态驱动条件渲染:

if (!this.completed) {
  Column() {
    // 步骤图标 + 标题 + 描述
    Row() {
      Text(this.steps[this.currentStep].icon).fontSize(36)
      Column() {
        Text(this.steps[this.currentStep].title)
          .fontSize(18).fontColor('#1a1a2e').fontWeight(FontWeight.Bold)
        Text(this.steps[this.currentStep].desc)
          .fontSize(13).fontColor('#666677').lineHeight(20)
      }
    }
    // 模拟表单内容
    Column() { /* placeholder fields */ }
    // 导航按钮
    Row() {
      if (this.currentStep > 0) {
        Text('← 上一步').onClick(() => { this.goPrev(); })
      }
      Blank()
      Text(this.currentStep < this.steps.length - 1 ? '下一步 →' : '提交完成')
        .onClick(() => { this.goNext(); })
    }
  }
}

每个步骤有独立的图标(📋 / 👥 / 🎯 / ✅)、标题、描述和模拟内容区域。在实际应用中,模拟内容区域会替换为真实的表单输入、选择器或其他交互组件。

3.2 导航逻辑

上一步和下一步的边界逻辑:

goNext(): void {
  if (this.currentStep < this.steps.length - 1) {
    this.currentStep = this.currentStep + 1;  // 进入下一步
  } else {
    this.completed = true;  // 最后一步 → 完成
  }
}

goPrev(): void {
  if (this.currentStep > 0) {
    this.currentStep = this.currentStep - 1;  // 返回上一步
  }
}

关键边界处理:

  • 第一步时"上一步"按钮隐藏(if (this.currentStep > 0)
  • 最后一步时按钮文字变为"提交完成"(this.currentStep < this.steps.length - 1 ? '下一步 →' : '提交完成'
  • 最后一步点击"提交完成"后触发 completed = true,展示完成状态

"上一步"按钮使用灰色(#F2F3F5),表示这是一个次要/辅助操作。"下一步"按钮使用当前步骤的主题色,表示这是主要操作。视觉层次清晰:主操作 > 辅操作。

3.3 步骤颜色独立

每个步骤有独立的主题色:

  • 基础信息 → 蓝色(#1677FF
  • 团队配置 → 绿色(#00B894
  • 目标设定 → 橙色(#E09F3E
  • 确认提交 → 紫色(#6C5CE7

进入不同步骤时,导航按钮的颜色随之变化。这种颜色变化是一种微妙的"上下文提示"——用户不需要读标题就能感知步骤已变化。
![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/53da918439f04202b91a46d315c64e37.png## 四、快速跳转面板
![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/c2182a07bb2a4ee5b2cfbd956c7c290c.png
在步骤内容下方,一个快速跳转面板列出所有步骤的概要信息和状态:

ForEach(this.steps, (step: StepItem, idx: number) => {
  Row() {
    // 编号圆点
    Column() {
      Text((idx + 1).toString())
        .fontSize(12)
        .fontColor(idx <= this.currentStep ? '#FFFFFF' : '#9999AA')
        .fontWeight(FontWeight.Bold)
    }
    .width(22).height(22).justifyContent(FlexAlign.Center).borderRadius(11)
    .backgroundColor(idx <= this.currentStep ? step.color : '#F2F3F5')

    // 步骤标题
    Text(step.title)
      .fontSize(13)
      .fontColor(idx === this.currentStep ? step.color : '#666677')
      .fontWeight(idx === this.currentStep ? FontWeight.Bold : FontWeight.Normal)
      .margin({ left: 10 })

    Blank()

    // 状态标签
    if (idx === this.currentStep) {
      Text('当前').fontSize(10).fontColor(step.color)
        .backgroundColor(step.color.concat('15'))
    } else if (idx < this.currentStep) {
      Text('已完成').fontSize(10).fontColor('#00B894')
        .backgroundColor('#00B89415')
    } else {
      Text('待完成').fontSize(10).fontColor('#BBBBCC')
    }
  }
  .width('100%').padding({ top: 8, bottom: 8 })
  .onClick(() => { this.goToStep(idx); })
})

每一行包含三个信息维度:

  1. 编号圆点(视觉状态):已完成/当前 → 主题色实心;待完成 → 灰色
  2. 步骤标题(文字内容):当前步骤 → 主题色加粗;其他 → 灰色
  3. 状态标签(文字状态):当前 / 已完成(绿色) / 待完成(灰色)

三态标签让用户在任何时刻都能快速了解"已经做了什么、正在做什么、还剩下什么"。这对于超过 3 步的长流程尤为重要。
在这里插入图片描述

五、完成状态

所有步骤完成后,展示一个简洁的成功反馈页:

if (this.completed) {
  Column() {
    Text('🎉').fontSize(56).margin({ bottom: 12 })
    Text('提交成功!')
      .fontSize(20).fontColor('#1a1a2e').fontWeight(FontWeight.Bold)
      .margin({ bottom: 6 })
    Text('项目创建向导已完成,您可以开始使用了。')
      .fontSize(14).fontColor('#666677')
      .margin({ bottom: 24 })
    Text('重新开始')
      .fontSize(14).fontColor('#FFFFFF').fontWeight(FontWeight.Medium)
      .padding({ top: 10, bottom: 10, left: 24, right: 24 })
      .borderRadius(8).backgroundColor('#1677FF')
      .onClick(() => { this.resetSteps(); })
  }
  .width('100%').padding({ top: 40, bottom: 40 })
  .justifyContent(FlexAlign.Center)
}

完成页包含三个元素:

  1. 情感化反馈:大号 emoji(🎉)+ 醒目标题,给予完成操作的成就感
  2. 确认信息:简洁描述已完成的操作
  3. 重新开始:重置按钮,方便用户再次走一遍流程

resetSteps()currentStep 重置为 0、completed 重置为 false,所有状态回到初始:

resetSteps(): void {
  this.currentStep = 0;
  this.completed = false;
}

简单的两个状态变量控制整个流程的展示——这就是步骤引导模式的简洁之处:不需要复杂的状态机,只需一个当前索引和一个完成标记。

六、完整交互流程

  1. 初始状态:进入页面,步骤 1(基础信息)高亮,进度指示器显示第 1 个圆点实色、其余灰色,快速跳转显示"当前 / 待完成 / 待完成 / 待完成"
  2. 前进:点击"下一步",currentStep 变为 1,圆点 1 显示 ✓(已完成),圆点 2 高亮(当前),步骤内容切换为"团队配置"
  3. 后退:点击"上一步",返回步骤 1,圆点 2 恢复灰色
  4. 快速跳转:点击跳转面板中的步骤 3 行,直接跳到"目标设定";已完成步骤(1、2)显示绿色"已完成",步骤 3 显示蓝色"当前"
  5. 到达末尾:不断点击"下一步"直到步骤 4,按钮变为"提交完成"
  6. 完成提交:点击"提交完成",页面切换为成功反馈页,显示 🎉 和"提交成功"
  7. 重新开始:点击"重新开始",所有状态归零,回到步骤 1

七、进阶扩展方向

7.1 步骤验证

在实际应用中,每一步应该验证用户输入是否正确。在 goNext() 中增加验证逻辑——当前步骤不通过时,显示错误提示并阻止进入下一步。

goNext(): void {
  if (!this.validateStep(this.currentStep)) {
    return; // 阻止前进
  }
  // ... 正常前进逻辑
}

7.2 数据持久化

在步骤之间保持用户已输入的数据。当用户返回上一步修改信息时,之前填写的内容应该保留(而不是清空)。这需要将每个步骤的表单数据存储在 @State 对象中。

7.3 渐进式保存

每完成一步自动保存该步骤的数据。即使中途退出,已完成的步骤数据也不会丢失。可以使用 PersistentStorage 或本地数据库实现。

7.4 跳过可选步骤

某些步骤可能是可选的(如"团队配置"对于单人项目)。在步骤标题旁增加"跳过"链接,允许用户跳过非必填的步骤。跳过后的步骤状态从"已完成"变为"已跳过"(使用不同的视觉标记)。

7.5 步骤分支

复杂流程可能有分支——根据某一步的选择决定后续步骤。例如"是否同步到云端?"→ "是"增加云配置步骤,"否"跳过。这是步骤引导模式的高级用法,需要动态构建步骤列表。

八、总结

本文通过"项目创建向导"这个实战案例,展示了如何用基础 ArkUI 组件(Row、Column、Text、条件渲染)构建功能完整的步骤引导系统。核心知识点包括:

  1. Stepper 的设计原理:分步降低认知负担,渐进式信息披露
  2. 进度指示器:圆点三态(完成/进行/待完成)+ 连接线 + 点击跳转
  3. 步骤内容与导航:条件渲染 + 边界逻辑 + 上一步/下一步按钮
  4. 快速跳转面板:全步骤列表 + 三态标签(当前/已完成/待完成)
  5. 完成状态:情感化反馈 + 重置入口
  6. 状态管理:仅两个 @State 变量(currentStep + completed)控制整个流程

步骤引导模式的简洁性体现在:不需要复杂的路由器或状态机,仅用条件渲染和两个状态变量就能实现完整的流程导航。这种模式不仅是项目创建向导的基础,也是注册流程、结账流程、任务引导、意见反馈等任何"多步骤操作"的标准解决方案。


Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐