☰
ant-design-blazor Steps 步骤切换实战:用 Steps、内容与按钮表达流程进度
2026/10/12 1:26:56 网站建设 项目流程
  • UI组件
  • 前端

【免费下载链接】ant-design-blazor

🌈A rich set of enterprise-class UI components based on Ant Design and Blazor.

项目地址:https://gitcode.com/gh_mirrors/an/ant-design-blazor
点击查看免费下载

在 ant-design-blazor 中,步骤切换是 Steps 组件最典型的应用形态:Steps负责展示流程节点与当前进度,其下方的内容区与按钮组负责承载每一步的具体操作,三者配合即可表达一个流程的处理进度。读完本篇,你将掌握如何用Steps的Current参数驱动 UI 状态切换、如何在最后一步通过IMessageService给出完成反馈,以及从源码层面理解Step的状态(wait/process/finish/error)是如何由Current自动推导出来的。

一、场景说明:通常配合内容及按钮使用

官方示例文档step-next.md对该场景的定义很简洁:

通常配合内容及按钮使用,表示一个流程的处理进度。

这正是企业级多步表单(如开通向导、审批流程、配置引导)的通用模式:

  • 顶部Steps步骤条:展示总步骤数与当前所处步骤;
  • 中部内容区:根据current索引渲染当前步骤的正文;
  • 底部按钮组:Previous(上一步)与Next(下一步)推进current,最后一步显示Done并给出成功反馈。

对应的完整示例组件位于 StepNext.razor,下面逐段解析。

二、完整示例代码解读

<div> <Steps Current="current"> @foreach (var item in steps) { <Step Title="@item.Title" Subtitle="@item.Content" /> } </Steps> <div class="steps-content"> @steps[current].Content </div> <div class="steps-action"> @if (current > 0) { <Button Type="ButtonType.Primary" OnClick="OnPreClick">Previous</Button> } @if (current < steps.Length - 1) { <Button Type="ButtonType.Primary" OnClick="OnNextClick">Next</Button> } @if (current == steps.Length - 1) { <Button Type="ButtonType.Primary" OnClick=@(() => message.Success("Processing complete!"))> Done </Button> } </div> </div>
@inject IMessageService message @code { public class StepItem { public string Title { get; set; } public string Content { get; set; } } public int current { get; set; } = 0; public StepItem[] steps = { new StepItem {Title = "First", Content = "First-content"}, new StepItem {Title = "Second", Content = "Second-content"}, new StepItem {Title = "Third", Content = "Third-content"}, new StepItem {Title = "Last", Content = "Last-content"} }; void OnPreClick() { current--; } void OnNextClick() { current++; } }

代码可以拆成三个关键点:

  1. 单一状态源:public int current是整个流程的唯一状态。Steps Current="current"把该状态绑定到步骤条;内容区@steps[current].Content与按钮组的三个@if分支也全部由它驱动。这是 Blazor 中"状态单向流动"的标准写法——修改current后,OnParametersSet会重新执行,步骤条、内容区、按钮区同步刷新。
  2. 按钮的条件渲染:Previous仅在current > 0时出现,Next仅在未到末尾时出现,Done仅在最后一步出现。与"渲染但禁用"不同,这种条件渲染可以直接消除无效入口。
  3. 完成反馈:Done的OnClick使用 lambda 调用message.Success("Processing complete!")。这里的message是注入的IMessageService,Success的完整签名为void Success(OneOf<string, RenderFragment, MessageConfig> content, double? duration = null, Action onClose = null)(见 IMessageService.cs),即内容可以是字符串、RenderFragment或MessageConfig,并可选指定停留时长与关闭回调。

深色主题下的样式适配

示例文档中还附带了一段专门针对深色主题的样式覆盖(见 step-next.md):

<style> [data-theme="dark"] .steps-content { margin-top: 16px; border: 1px dashed #303030; background-color: rgba(255,255,255,0.04); color: rgba(255,255,255,0.65); padding-top: 80px; } </style>

而示例组件 StepNext.razor 内同时内置了浅色主题的.steps-content(虚线边框、#fafafa背景、min-height: 200px、顶部padding-top: 80px)。两者共同说明一个实践细节:步骤内容区属于业务自绘区域,不随组件主题自动换肤,如果项目启用了[data-theme="dark"]深色模式,需要自行补充对应的深色变体。

三、Steps 与 Step 的关键参数

结合 Steps 文档 API 与 Steps.razor.cs 中的实际[Parameter]声明,本场景最相关的参数如下:

Steps(步骤条整体)

参数说明类型默认值
Current指定当前步骤,从 0 开始计数;子Step可用Status覆盖状态int0
Direction步骤条方向,StepsDirection.Horizontal/VerticalStepsDirectionHorizontal
LabelPlacement标签放置位置,可选Vertical放图标下方StepsLabelPlacementHorizontal
Type步骤条类型,StepsType.Default/NavigationStepsTypeDefault
Size尺寸,StepsSize.Default/SmallStepsSizeDefault
Status当前步骤状态:Wait/Process/Finish/ErrorStepsStatusProcess
StartIndex起始序号(文档中写作Initial),从 0 计数int0
Percent当前步骤的百分比进度(文档 API 表未列出,源码中支持)double?null
OnChange点击切换步骤时触发,参数为目标步骤索引EventCallback<int>-

Step(单个步骤)

参数说明类型默认值
Title/Subtitle标题与子标题stringstring.Empty
Description步骤详情描述stringstring.Empty
Icon步骤图标类型(IconType)string-
Status手动指定状态;不配置时由Steps的Current自动推导StepsStatus自动
Disabled禁用点击boolfalse
OnClick点击步骤时的回调EventCallback<MouseEventArgs>-

注意 Blazor 版与 React 版的差异:方向、尺寸、状态等在 StepsDirection.cs、StepsSize.cs、StepsStatus.cs 等文件中都是强类型枚举,例如Direction="StepsDirection.Vertical"、Status="StepsStatus.Error",在模板中获得编译期检查。

四、源码剖析:Current 如何驱动每一步的状态

4.1 子步骤注册与级联下发

Steps通过CascadingValue把自己下发给子树(见 Steps.razor):

<CascadingValue Value="this" IsFixed="@true"> <div class="@ClassMapper.Class" style="@Style" id="@Id" @ref="Ref"> @ChildContent </div> </CascadingValue>

每个Step在OnInitialized中通过[CascadingParameter] public Steps Parent取得父级并调用Parent.AddStep(this)完成注册(见 Step.razor.cs)。AddStep记下索引后触发ResetChildrenSteps()(Steps.razor.cs):

_children[i].GroupStatus = this.Status; _children[i].GroupCurrentIndex = this.Current; _children[i].Index = i + this.StartIndex; ...

关键点:Steps每次参数变化(OnParametersSet)都会重新执行ResetChildrenSteps,把Current、Status、Direction、Size等"群组级"状态重新同步到每一个Step。这就是示例中修改current后整条步骤条立即刷新的底层原因。

4.2 状态自动推导逻辑

Step中并没有为每一步单独维护状态,而是在GroupCurrentIndex的 setter 中自动计算(Step.razor.cs):

internal int GroupCurrentIndex { get => _groupCurrent; set { _groupCurrent = value; if (!_isCustomStatus) { this._status = value > this.Index ? StepsStatus.Finish : value == this.Index ? GroupStatus ?? null : StepsStatus.Wait; } InvokeStateHasChanged(); } }

即:索引小于Current的步骤为Finish,等于Current的取Steps.Status(默认Process),大于Current的为Wait;只有显式给Step设置过Status(_isCustomStatus == true)时才会跳过自动推导。示例 StepNext.razor 中的 4 个Step全部依赖这一自动推导:current为 0 时第一步是process,其余是wait;推进到第 3 步时前 3 步全部变为finish。

4.3 状态到视觉的映射

SetClassMap负责把状态翻译成 CSS 类(Step.razor.cs):ant-steps-item-{wait|process|finish|error}标记状态,ant-steps-item-active标记当前步骤,ant-steps-item-disabled标记禁用,并额外处理了"上一步出错"的ant-steps-next-error样式。图标渲染则在 Step.razor:未配置Icon时,Finish显示对勾、Error显示叉号、Process/Wait显示序号Index + 1;配置了Icon时除Error状态外显示指定图标。

测试用例 StepsTests.razor 对上述行为做了覆盖,例如Step_renders_number_and_finish_and_error_and_progress_dot验证Current="1"时第一项显示数字、第二项携带ant-steps-item-finish类;Next_error_class_is_applied_when_group_status_error验证了ant-steps-next-error的触发条件。

五、扩展方向:让步骤条本身可点击

本示例通过外部按钮控制current;如果希望用户直接点击步骤条跳转,只需给Steps传入OnChange。从源码看,OnChange.HasDelegate决定了子步骤是否可点击(ResetChildrenSteps中Clickable = OnChange.HasDelegate,见 Steps.razor.cs);点击时HandleClick会调用Parent.NavigateTo(Index),后者更新Current并异步触发OnChange.InvokeAsync(current)(Steps.razor.cs)。对应官方示例见 Clickable.razor 及其说明 clickable.md:"设置OnChange后,Steps 变为可点击状态"。两种模式也完全可以混用:保留 Previous/Next 按钮做主流程,同时用OnChange允许用户回看已完成步骤——只需在OnClick/OnChange中把current赋为目标索引即可。

其他相关演示可在 Steps demo 目录 中找到:Progress(带百分比进度)、ProgressDot/CustomizedProgressDot(点状步骤条)、Nav(导航型)、Error(出错状态)、Vertical(竖直方向)等。

六、实践要点小结

  1. 以单一current状态驱动全部 UI:步骤条、内容区、按钮组都从它派生,避免多处状态不一致;
  2. 按钮按边界条件渲染:首步不显示Previous,末步把Next替换为Done,末步回调里用IMessageService.Success给出反馈;
  3. 状态交给组件自动推导:不要为每个Step手填Status,除非确需覆盖(如某步长期处于Error);
  4. 深色主题需自补样式:内容区是自绘区域,记得为[data-theme="dark"]准备变体;
  5. 需要可点击跳转时添加OnChange,它会同时让步骤获得role="button"与tabindex等可访问性属性(StepsTests.razor 中的Tabindex_and_role_are_set_for_clickable_steps验证了这一点)。

核心文件索引:

  • 示例文档:step-next.md
  • 示例组件:StepNext.razor
  • 组件实现:Steps.razor.cs、Step.razor.cs、Step.razor
  • 消息服务:IMessageService.cs
  • 组件文档:index.zh-CN.md
  • 单元/组件测试:StepsTests.razor
  • UI组件
  • 前端

【免费下载链接】ant-design-blazor

🌈A rich set of enterprise-class UI components based on Ant Design and Blazor.

项目地址:https://gitcode.com/gh_mirrors/an/ant-design-blazor
点击查看免费下载
上一篇:从零开始构建神经网络框架:AI初学者指南
下一篇:RapidOCR 推理提速指南:多引擎选型的 5 个关键手段与落地配置

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询