HTML步骤条是纯视觉组件,仅通过类名或属性显示进度,不控制流程;流程引导需独立实现校验、跳转、回退及状态同步,二者职责必须分离。

HTML步骤条和流程引导不是同一类东西,不能直接互换。步骤条是视觉组件,流程引导是交互逻辑——前者只负责“画出进度”,后者要决定“什么时候走哪步”“用户能不能退回”“当前步是否校验通过”。混淆这两者,会导致界面显示和实际状态脱节。
步骤条只是状态显示器,不控制流程走向
一个 <ol class="steps"> 里有四个 <li>,哪怕你用 JavaScript 把第 3 个加了 class="active",它也不会自动阻止用户跳到第 4 步,也不会校验第 2 步表单是否填完。它没有内置的“下一步”逻辑,也不感知业务规则。
- 步骤条渲染依赖类名(如
active、completed)或data-step属性,但这些值必须由外部代码设置 - 如果流程引导逻辑没同步更新步骤条类名,就会出现“按钮已点下一步,但步骤条还停在上一步”的错位
- 纯 CSS 实现的步骤条(无 JS)完全静态,连点击响应都没有,更谈不上引导
流程引导必须自己实现校验、跳转、回退和状态同步
真正的流程引导需要监听用户动作,并在每一步执行具体检查。比如注册流程中,“验证身份”这步必须等短信验证码输入且校验通过后,才允许触发 goToStep(3)。
- 每步应有明确的
canProceed()判断函数,而不是仅靠按钮是否可点击 - “上一步”不能简单
stepIndex--,要检查是否允许回退(例如支付成功后禁止返回修改收货地址) - 步骤条更新必须放在校验通过之后,而不是点击按钮的瞬间——否则容易出现“视觉已前进,但接口报错回滚”的体验断层
- 推荐把步骤状态存在一个统一对象里,如
{ step: 2, completed: [1], locked: [3] },再驱动 UI 和按钮行为
用自定义元素封装时,别把逻辑塞进步骤条组件里
有人用 customElements.define('step-indicator', ...) 封装步骤条,然后在里面加 next()、prev() 方法——这是反模式。步骤条组件只该响应 currentStep 属性变化并重绘,不该持有流程状态或发起 API 请求。
立即学习“前端免费学习笔记(深入)”;
- 把流程控制器(如
RegistrationFlow类)和 UI 组件(step-indicator)职责分开,用事件通信(如dispatchEvent(new CustomEvent('stepchange')))而非直接调用方法 - 如果步骤条内部偷偷修改了
stepIndex并触发跳转,会破坏外部对流程的掌控力,调试时很难定位状态变更源头 - 无障碍支持(如屏幕阅读器播报“当前第2步,共4步”)也依赖外部传入的语义化状态,不是组件自己猜的
最常被忽略的一点:步骤条的 DOM 结构必须保持语义正确性。用 <ol> 而不是一堆 <div>,不仅是为了样式方便,更是为了让键盘用户按 Tab 时能自然按顺序聚焦每个步骤节点——这点在流程引导中一旦出错,整个路径就不可访问了。



















