Vant Steps 步骤条组件完全指南:状态机制、API 配置与主题定制
2026/9/13 1:21:09 网站建设 项目流程

Vant Steps 步骤条组件完全指南:状态机制、API 配置与主题定制

【免费下载链接】vantA lightweight, customizable Vue UI library for mobile web apps.项目地址: https://gitcode.com/GitHub_Trending/va/vant

导读

Steps是 Vant 移动端组件库中用于展示操作流程的步骤条组件,它把“买家下单 → 商家接单 → 买家提货 → 交易完成”这类流程拆解为带状态的可视化节点,帮助用户实时了解当前操作在整体流程中的位置。本指南以 Steps 官方文档 为骨架,结合 Vant 仓库内StepsStep两个组件的源码实现、演示用例与测试用例,系统讲解组件的引入方式、基础用法、状态判定原理、完整 API、插槽体系与 CSS 变量主题定制,读完即可在真实业务中正确使用并深度定制步骤条。

组件介绍与引入

什么是 Steps 步骤条

步骤条用于将一项复杂操作拆解为若干连续环节,让用户明确“现在进行到哪一步、还剩几步”。在 Vant 中它由两个组件协作完成:

  • Steps:外层容器,负责接收activedirection等全局配置;
  • Step:内层节点,每个van-step渲染一个步骤,状态由Steps根据索引统一推导。

在 Steps.tsx 中,外层组件通过useChildren建立与子节点Step的关联,并把自身propsonClickStep回调下发给每个子步骤,从而实现“父组件统管状态、子组件自主渲染”的协作模型。

引入方式

通过以下方式来全局注册组件,更多注册方式可参考 组件注册文档:

import { createApp } from 'vue'; import { Step, Steps } from 'vant'; const app = createApp(); app.use(Step); app.use(Steps);

从源码看,StepsStep都通过withInstall包装导出,并声明了VanStepsVanStep全局组件类型(见 steps/index.ts 与 step/index.ts),因此注册后即可在模板中使用<van-steps><van-step>标签。

基础用法

active属性表示当前步骤的索引,从 0 起计。以下示例中active = 1,表示第 2 个步骤“商家接单”为进行中状态:

<van-steps :active="active"> <van-step>买家下单</van-step> <van-step>商家接单</van-step> <van-step>买家提货</van-step> <van-step>交易完成</van-step> </van-steps>
import { ref } from 'vue'; export default { setup() { const active = ref(1); return { active }; }, };

状态是如何推导的:三步状态机

在 Step.tsx 中,每个步骤的状态完全由“自身索引”与“父组件的 active”比较得出:

const getStatus = () => { const active = +parentProps.active; if (index.value < active) { return 'finish'; // 已完成 } return index.value === active ? 'process' : 'waiting'; // 进行中 / 待处理 };

即每个van-step只会处于三种状态之一:

状态判定条件视觉表现
finish(已完成)index < active连接线与节点使用完成态颜色(默认主色)
process(进行中)index === active节点显示激活图标(默认对勾checked
waiting(待处理)index > active节点显示未激活图标或灰色圆点

此外active支持传入number | string(源码中使用makeNumericProp(0)声明),字符串数字会被自动转换比较,这在从接口拿到字符串索引时非常实用。

带“下一步”按钮的完整交互

仓库自带的 demo/index.vue 展示了真实业务中的典型联动——用按钮推进步骤:

<script setup lang="ts"> import { ref } from 'vue'; const active = ref(1); const nextStep = () => { active.value = ++active.value % 4; }; </script> <template> <van-steps :active="active"> <van-step>买家下单</van-step> <van-step>商家接单</van-step> <van-step>买家提货</van-step> <van-step>交易完成</van-step> </van-steps> <van-button @click="nextStep">下一步</van-button> </template>

active取模循环,4 步走完会重新回到第一步,适合订单状态循环演示场景。

自定义样式:图标与颜色

可以通过active-iconactive-color属性设置激活状态下的图标和颜色:

<van-steps :active="active" active-icon="success" active-color="#07c160"> <van-step>买家下单</van-step> <van-step>商家接单</van-step> <van-step>买家提货</van-step> <van-step>交易完成</van-step> </van-steps>

图标渲染优先级(源码级拆解)

从 Step.tsx 的renderCircle可以看到节点图标的完整渲染优先级:

  1. 进行中(process):优先渲染active-icon插槽,否则渲染<Icon name={activeIcon}>,颜色使用activeColor
  2. 已完成(finish):仅当配置了finishIconfinish-icon插槽时才渲染自定义完成图标(优先级高于inactive-icon),否则继续走下面的未激活分支;
  3. 未激活/兜底:优先inactive-icon插槽,其次渲染inactiveIcon图标,若都未配置则渲染一个纯 CSS 的圆点<i class="van-step__circle">(圆点颜色由连接线当前状态决定)。

同时,完成态连接线颜色通过lineStyle动态注入:状态为finish时使用activeColor,否则使用inactiveColor;标题文字颜色也按 process/waiting 状态分别取activeColor/inactiveColor。这解释了为什么active-color会同时影响“当前步骤和已完成步骤”的视觉。

竖向步骤条

可以通过设置direction属性把步骤条从水平改为垂直方向,常用于物流详情、审批流等需要展示时间与描述信息的场景:

<van-steps direction="vertical" :active="0"> <van-step> <h3>【城市】物流状态1</h3> <p>2016-07-12 12:40</p> </van-step> <van-step> <h3>【城市】物流状态2</h3> <p>2016-07-11 10:00</p> </van-step> <van-step> <h3>快件已发货</h3> <p>2016-07-10 09:30</p> </van-step> </van-steps>

竖向模式在样式层通过 step/index.less 中的.van-step--vertical实现:步骤改为块级布局、float: none,连接线变为左侧 1px 的竖直长线,节点圆点/图标定位于左侧居中;外层.van-steps--vertical(见 steps/index.less)则增加了左侧内边距为图标留位。两个方向都保证了最后一个步骤的连接线宽度为 0,不会出现多余的“尾巴”。

点击步骤与事件

Steps支持点击步骤的标题或图标区域时触发click-step事件,回调参数为被点击步骤的索引index: number

<van-steps :active="active" @click-step="onClickStep"> <van-step>买家下单</van-step> <van-step>商家接单</van-step> </van-steps>
function onClickStep(index) { active.value = index; // 点击跳转到对应步骤 console.log('当前点击了第', index, '步'); }

点击如何从子节点回传父组件

事件链路依赖父子组件通信:在 Steps.tsx 中,父组件定义onClickStep = (index) => emit('clickStep', index)并通过linkChildren注入;子组件 Step.tsx 在标题(.van-step__title)和节点容器(.van-step__circle-container)上都绑定了onClick,点击时调用parent.onClickStep(index.value)

steps/test/index.spec.tsx 中的测试精确验证了这一行为:

wrapper.find('.van-step__title').trigger('click'); expect(onClickStep).toHaveBeenCalledWith(0); wrapper.findAll('.van-step__circle-container')[2].trigger('click'); expect(onClickStep).toHaveBeenLastCalledWith(2);

测试还验证了点击步骤容器本身(非标题、非图标区域)不会触发事件,说明事件只绑定在可交互区域上。

API 详解

Steps Props

参数说明类型默认值
active当前步骤对应的索引值number | string0
direction步骤条方向,可选值为verticalstringhorizontal
active-icon当前步骤对应的底部图标,可选值见 Icon 组件stringchecked
inactive-icon非当前步骤对应的底部图标,可选值见 Icon 组件string-
finish-icon已完成步骤对应的底部图标,优先级高于inactive-icon,可选值见 Icon 组件string-
active-color当前步骤和已完成步骤的颜色string#1989fa
inactive-color未激活步骤的颜色string#969799
icon-prefix图标类名前缀,等同于 Icon 组件的 class-prefix 属性stringvan-icon

对照源码 Steps.tsx 中的stepsProps声明,可补充以下实现细节:

  • active使用makeNumericProp(0)声明,同时接受数字与数字字符串;
  • direction使用makeStringProp('horizontal')声明,可选值即StepsDirection联合类型'horizontal' | 'vertical'
  • iconPrefix会被透传给内部<Icon>classPrefix,默认van-icon,用于自定义图标库时替换类名前缀。测试should render icon-prefix correctly验证了传入iconPrefix="custom-icon"后渲染为van-icon-custom-icon前缀的类名;
  • activeColorinactiveColor未设置默认值,实际生效默认色来自 CSS 变量层(--van-primary-color对应#1989fa--van-gray-6对应#969799)。

Step Slots

名称说明
default步骤内容
active-icon自定义激活状态图标
inactive-icon自定义未激活状态图标
finish-icon自定义已完成步骤对应的底部图标,优先级高于inactive-icon

插槽使用示例(可传入任意自定义内容,如自定义 SVG 图标):

<van-steps :active="1"> <van-step> <template #active-icon> <van-icon name="success" color="#07c160" /> </template> <template #finish-icon> <van-icon name="passed" color="#1989fa" /> </template> <template #inactive-icon> <van-icon name="circle" color="#969799" /> </template> 买家下单 </van-step> </van-steps>

steps/test/index.spec.tsx 中should render icon slot correctlyshould render finish icon slot correctly两个用例分别验证了active-icon/inactive-icon/finish-icon插槽的渲染结果,说明插槽方案与属性方案并存且插槽优先级更高。

Steps Events

事件名说明回调参数
click-step点击步骤的标题或图标时触发index: number

类型定义

组件导出以下类型定义,可在 TypeScript 项目中获得完整的类型提示:

import type { StepsProps, StepsDirection } from 'vant';

相关类型的源码定义位置:

  • StepsProps:由stepsProps通过ExtractPropTypes推导(Steps.tsx);
  • StepsDirection'horizontal' | 'vertical'字面量联合类型(同上);
  • StepsThemeVars:主题变量类型{ stepsBackground?: string }(types.ts)。

以上类型均在 index.ts 中统一 re-export。

主题定制:CSS 变量

组件提供了下列 CSS 变量,可用于自定义样式。推荐配合 ConfigProvider 组件 在应用层统一覆盖:

名称默认值描述
--van-step-text-colorvar(--van-text-color-2)步骤文字颜色
--van-step-active-colorvar(--van-primary-color)激活状态颜色
--van-step-process-text-colorvar(--van-text-color)进行中步骤文字颜色
--van-step-font-sizevar(--van-font-size-md)步骤字体大小
--van-step-line-colorvar(--van-border-color)连接线颜色
--van-step-finish-line-colorvar(--van-primary-color)已完成连接线颜色
--van-step-finish-text-colorvar(--van-text-color)已完成步骤文字颜色
--van-step-icon-size12px步骤图标大小
--van-step-circle-size5px圆点直径
--van-step-circle-colorvar(--van-gray-6)圆点颜色
--van-step-horizontal-title-font-sizevar(--van-font-size-sm)水平方向标题字体大小
--van-steps-backgroundvar(--van-background-2)步骤条背景色

提示:以上变量分为两组定义——--van-step-*系列定义在 step/index.less 的:root, :host中,--van-steps-background定义在 steps/index.less 中,两者都可以通过 ConfigProvider 或:root覆盖。

使用示例(全局覆盖为绿色主题):

<van-config-provider :theme-vars="{ stepActiveColor: '#07c160', stepFinishLineColor: '#07c160', }" > <van-steps :active="1"> <van-step>买家下单</van-step> <van-step>商家接单</van-step> </van-steps> </van-config-provider>

小结

Steps 组件麻雀虽小五脏俱全:外层Steps通过useChildren统一管理active索引并向下分发配置,内层Step依据“索引与 active 的大小关系”自动推导finish / process / waiting三态;图标渲染遵循“插槽 > 属性 > CSS 圆点兜底”的优先级,click-step事件只绑定在标题与节点可点击区域。结合本文给出的 演示代码、源码实现 与 测试用例,开发者可以放心地将步骤条用于订单跟踪、表单分步引导、物流详情等移动端场景,并通过 Props、插槽与 CSS 变量三层机制完成灵活定制。

【免费下载链接】vantA lightweight, customizable Vue UI library for mobile web apps.项目地址: https://gitcode.com/GitHub_Trending/va/vant

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

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

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

立即咨询