- UI组件
- 前端
【免费下载链接】ant-design-blazor
🌈A rich set of enterprise-class UI components based on Ant Design and 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++; } }代码可以拆成三个关键点:
- 单一状态源:
public int current是整个流程的唯一状态。Steps Current="current"把该状态绑定到步骤条;内容区@steps[current].Content与按钮组的三个@if分支也全部由它驱动。这是 Blazor 中"状态单向流动"的标准写法——修改current后,OnParametersSet会重新执行,步骤条、内容区、按钮区同步刷新。 - 按钮的条件渲染:
Previous仅在current > 0时出现,Next仅在未到末尾时出现,Done仅在最后一步出现。与"渲染但禁用"不同,这种条件渲染可以直接消除无效入口。 - 完成反馈:
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覆盖状态 | int | 0 |
Direction | 步骤条方向,StepsDirection.Horizontal/Vertical | StepsDirection | Horizontal |
LabelPlacement | 标签放置位置,可选Vertical放图标下方 | StepsLabelPlacement | Horizontal |
Type | 步骤条类型,StepsType.Default/Navigation | StepsType | Default |
Size | 尺寸,StepsSize.Default/Small | StepsSize | Default |
Status | 当前步骤状态:Wait/Process/Finish/Error | StepsStatus | Process |
StartIndex | 起始序号(文档中写作Initial),从 0 计数 | int | 0 |
Percent | 当前步骤的百分比进度(文档 API 表未列出,源码中支持) | double? | null |
OnChange | 点击切换步骤时触发,参数为目标步骤索引 | EventCallback<int> | - |
Step(单个步骤)
| 参数 | 说明 | 类型 | 默认值 |
|---|---|---|---|
Title/Subtitle | 标题与子标题 | string | string.Empty |
Description | 步骤详情描述 | string | string.Empty |
Icon | 步骤图标类型(IconType) | string | - |
Status | 手动指定状态;不配置时由Steps的Current自动推导 | StepsStatus | 自动 |
Disabled | 禁用点击 | bool | false |
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(竖直方向)等。
六、实践要点小结
- 以单一
current状态驱动全部 UI:步骤条、内容区、按钮组都从它派生,避免多处状态不一致; - 按钮按边界条件渲染:首步不显示
Previous,末步把Next替换为Done,末步回调里用IMessageService.Success给出反馈; - 状态交给组件自动推导:不要为每个
Step手填Status,除非确需覆盖(如某步长期处于Error); - 深色主题需自补样式:内容区是自绘区域,记得为
[data-theme="dark"]准备变体; - 需要可点击跳转时添加
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.
相关推荐
antd Steps 步骤切换实战:基于 current 状态与按钮驱动多步流程
antd Steps 步骤切换实战:基于 current 状态与按钮驱动多步流程 导读 在 Ant Design 的 Steps 步骤条组件中,"步骤切换"(s
前端UI组件设计系统5步精通Ant Design Blazor步骤条组件:Steps实战指南
5步精通Ant Design Blazor步骤条组件:Steps实战指南 Ant Design Blazor是一个基于Ant Design设计语言的企业级Bla
UI组件前端Ant Design Steps 步骤条实战:实现"切换到下一步"的动态推进与循环逻辑
Ant Design Steps 步骤条实战:实现"切换到下一步"的动态推进与循环逻辑 本篇技术指南以 ant design 仓库中 step next.md
UI组件前端设计系统
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考