介绍
引导用户按照流程完成任务的分步导航条。
代码演示
基础使用
使用 current 属性指定步骤的下标,小于这个下标的步骤状态为 finish,等于这个下标的步骤状态为 process,大于这个下标的步骤状态为 wait。
vue
<template>
<s-list card>
<s-list-item title="上一步" @click="prevStep" arrow hover />
<s-list-item title="下一步" @click="nextStep" arrow hover />
<s-list-item>
<s-steps :current="current" :item-list="itemList" />
</s-list-item>
</s-list>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { type StepsItem } from 'sard'
const current = ref(1)
const itemList: StepsItem[] = [{ name: '步骤1' }, { name: '步骤2' }, { name: '步骤3' }]
const prevStep = () => {
current.value = current.value <= 0 ? 3 : current.value - 1
}
const nextStep = () => {
current.value = current.value >= 3 ? 0 : current.value + 1
}
</script>vue
<template>
<s-list card>
<s-list-item title="上一步" @click="prevStep" arrow hover />
<s-list-item title="下一步" @click="nextStep" arrow hover />
<s-list-item>
<s-steps :current="current" :item-list="itemList" />
</s-list-item>
</s-list>
</template>
<script setup lang="js">
import { ref } from 'vue'
import 'sard'
const current = ref(1)
const itemList = [{ name: '步骤1' }, { name: '步骤2' }, { name: '步骤3' }]
const prevStep = () => {
current.value = current.value <= 0 ? 3 : current.value - 1
}
const nextStep = () => {
current.value = current.value >= 3 ? 0 : current.value + 1
}
</script>居中
居中每个步骤的图标和文案。
vue
<template>
<s-list card>
<s-list-item title="上一步" @click="prevStep" arrow hover />
<s-list-item title="下一步" @click="nextStep" arrow hover />
<s-list-item>
<s-steps :current="current" center :item-list="itemList" />
</s-list-item>
</s-list>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { type StepsItem } from 'sard'
const current = ref(1)
const itemList: StepsItem[] = [{ name: '步骤1' }, { name: '步骤2' }, { name: '步骤3' }]
const prevStep = () => {
current.value = current.value <= 0 ? 3 : current.value - 1
}
const nextStep = () => {
current.value = current.value >= 3 ? 0 : current.value + 1
}
</script>vue
<template>
<s-list card>
<s-list-item title="上一步" @click="prevStep" arrow hover />
<s-list-item title="下一步" @click="nextStep" arrow hover />
<s-list-item>
<s-steps :current="current" center :item-list="itemList" />
</s-list-item>
</s-list>
</template>
<script setup lang="js">
import { ref } from 'vue'
import 'sard'
const current = ref(1)
const itemList = [{ name: '步骤1' }, { name: '步骤2' }, { name: '步骤3' }]
const prevStep = () => {
current.value = current.value <= 0 ? 3 : current.value - 1
}
const nextStep = () => {
current.value = current.value >= 3 ? 0 : current.value + 1
}
</script>文字在上
可以使用 reverse 属性将水平排列时的文字和图标位置调换。
vue
<template>
<s-list card>
<s-list-item title="上一步" @click="prevStep" arrow hover />
<s-list-item title="下一步" @click="nextStep" arrow hover />
<s-list-item>
<s-steps :current="current" reverse :item-list="itemList" />
</s-list-item>
</s-list>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { type StepsItem } from 'sard'
const current = ref(1)
const itemList: StepsItem[] = [{ name: '步骤1' }, { name: '步骤2' }, { name: '步骤3' }]
const prevStep = () => {
current.value = current.value <= 0 ? 3 : current.value - 1
}
const nextStep = () => {
current.value = current.value >= 3 ? 0 : current.value + 1
}
</script>vue
<template>
<s-list card>
<s-list-item title="上一步" @click="prevStep" arrow hover />
<s-list-item title="下一步" @click="nextStep" arrow hover />
<s-list-item>
<s-steps :current="current" reverse :item-list="itemList" />
</s-list-item>
</s-list>
</template>
<script setup lang="js">
import { ref } from 'vue'
import 'sard'
const current = ref(1)
const itemList = [{ name: '步骤1' }, { name: '步骤2' }, { name: '步骤3' }]
const prevStep = () => {
current.value = current.value <= 0 ? 3 : current.value - 1
}
const nextStep = () => {
current.value = current.value >= 3 ? 0 : current.value + 1
}
</script>垂直步骤条
设置 direction="vertical" 可以垂直排列。
vue
<template>
<s-list card>
<s-list-item title="上一步" @click="prevStep" arrow hover />
<s-list-item title="下一步" @click="nextStep" arrow hover />
<s-list-item>
<s-steps :current="current" :item-list="itemList" direction="vertical" />
</s-list-item>
</s-list>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { type StepsItem } from 'sard'
const current = ref(1)
const itemList: StepsItem[] = [
{ name: '步骤1', description: '这是描述' },
{ name: '步骤2', description: '这是描述' },
{ name: '步骤3', description: '这是描述' },
]
const prevStep = () => {
current.value = current.value <= 0 ? 3 : current.value - 1
}
const nextStep = () => {
current.value = current.value >= 3 ? 0 : current.value + 1
}
</script>vue
<template>
<s-list card>
<s-list-item title="上一步" @click="prevStep" arrow hover />
<s-list-item title="下一步" @click="nextStep" arrow hover />
<s-list-item>
<s-steps :current="current" :item-list="itemList" direction="vertical" />
</s-list-item>
</s-list>
</template>
<script setup lang="js">
import { ref } from 'vue'
import 'sard'
const current = ref(1)
const itemList = [
{
name: '步骤1',
description: '这是描述',
},
{
name: '步骤2',
description: '这是描述',
},
{
name: '步骤3',
description: '这是描述',
},
]
const prevStep = () => {
current.value = current.value <= 0 ? 3 : current.value - 1
}
const nextStep = () => {
current.value = current.value >= 3 ? 0 : current.value + 1
}
</script>垂直居中
将图标和文案垂直居中。
vue
<template>
<s-list card>
<s-list-item title="上一步" @click="prevStep" arrow hover />
<s-list-item title="下一步" @click="nextStep" arrow hover />
<s-list-item>
<s-steps :current="current" :item-list="itemList" direction="vertical" center />
</s-list-item>
</s-list>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { type StepsItem } from 'sard'
const current = ref(1)
const itemList: StepsItem[] = [
{ name: '步骤1', description: '这是描述' },
{ name: '步骤2', description: '这是描述' },
{ name: '步骤3', description: '这是描述' },
]
const prevStep = () => {
current.value = current.value <= 0 ? 3 : current.value - 1
}
const nextStep = () => {
current.value = current.value >= 3 ? 0 : current.value + 1
}
</script>vue
<template>
<s-list card>
<s-list-item title="上一步" @click="prevStep" arrow hover />
<s-list-item title="下一步" @click="nextStep" arrow hover />
<s-list-item>
<s-steps :current="current" :item-list="itemList" direction="vertical" center />
</s-list-item>
</s-list>
</template>
<script setup lang="js">
import { ref } from 'vue'
import 'sard'
const current = ref(1)
const itemList = [
{
name: '步骤1',
description: '这是描述',
},
{
name: '步骤2',
description: '这是描述',
},
{
name: '步骤3',
description: '这是描述',
},
]
const prevStep = () => {
current.value = current.value <= 0 ? 3 : current.value - 1
}
const nextStep = () => {
current.value = current.value >= 3 ? 0 : current.value + 1
}
</script>自定义图标
使用 Step 组件 icon 插槽自定义图标。
vue
<template>
<s-list card>
<s-list-item title="上一步" @click="prevStep" arrow hover />
<s-list-item title="下一步" @click="nextStep" arrow hover />
<s-list-item>
<s-steps :current="current" :item-list="itemList" center>
<s-step
v-for="(item, i) in itemList"
:key="i"
:index="i"
:name="item.name"
:description="item.description"
>
<template #icon="{ status }">
<demo-icon v-if="status === 'finish'" name="star-fill" size="20px" />
<demo-icon v-else-if="status === 'process'" name="star" size="20px" />
<demo-icon v-else-if="status === 'wait'" name="star" size="20px" />
<demo-icon v-else-if="status === 'error'" name="star" size="20px" />
</template>
</s-step>
</s-steps>
</s-list-item>
</s-list>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { type StepsItem } from 'sard'
const current = ref(1)
const itemList: StepsItem[] = [{ name: '步骤1' }, { name: '步骤2' }, { name: '步骤3' }]
const prevStep = () => {
current.value = current.value <= 0 ? 3 : current.value - 1
}
const nextStep = () => {
current.value = current.value >= 3 ? 0 : current.value + 1
}
</script>vue
<template>
<s-list card>
<s-list-item title="上一步" @click="prevStep" arrow hover />
<s-list-item title="下一步" @click="nextStep" arrow hover />
<s-list-item>
<s-steps :current="current" :item-list="itemList" center>
<s-step
v-for="(item, i) in itemList"
:key="i"
:index="i"
:name="item.name"
:description="item.description"
>
<template #icon="{ status }">
<demo-icon v-if="status === 'finish'" name="star-fill" size="20px" />
<demo-icon v-else-if="status === 'process'" name="star" size="20px" />
<demo-icon v-else-if="status === 'wait'" name="star" size="20px" />
<demo-icon v-else-if="status === 'error'" name="star" size="20px" />
</template>
</s-step>
</s-steps>
</s-list-item>
</s-list>
</template>
<script setup lang="js">
import { ref } from 'vue'
import 'sard'
const current = ref(1)
const itemList = [{ name: '步骤1' }, { name: '步骤2' }, { name: '步骤3' }]
const prevStep = () => {
current.value = current.value <= 0 ? 3 : current.value - 1
}
const nextStep = () => {
current.value = current.value >= 3 ? 0 : current.value + 1
}
</script>自定义颜色
使用 css 变量设置元素样式。
vue
<template>
<s-list card>
<s-list-item title="上一步" @click="prevStep" arrow hover />
<s-list-item title="下一步" @click="nextStep" arrow hover />
<s-list-item>
<s-steps
:current="current"
:item-list="itemList"
center
style="
--s-steps-icon-color-finish: var(--s-color-warning);
--s-steps-icon-color-process: var(--s-color-warning);
--s-steps-text-color-process: var(--s-color-warning);
--s-steps-line-color-active: var(--s-color-warning);
"
/>
</s-list-item>
</s-list>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { type StepsItem } from 'sard'
const current = ref(1)
const itemList: StepsItem[] = [{ name: '步骤1' }, { name: '步骤2' }, { name: '步骤3' }]
const prevStep = () => {
current.value = current.value <= 0 ? 3 : current.value - 1
}
const nextStep = () => {
current.value = current.value >= 3 ? 0 : current.value + 1
}
</script>vue
<template>
<s-list card>
<s-list-item title="上一步" @click="prevStep" arrow hover />
<s-list-item title="下一步" @click="nextStep" arrow hover />
<s-list-item>
<s-steps
:current="current"
:item-list="itemList"
center
style="
--s-steps-icon-color-finish: var(--s-color-warning);
--s-steps-icon-color-process: var(--s-color-warning);
--s-steps-text-color-process: var(--s-color-warning);
--s-steps-line-color-active: var(--s-color-warning);
"
/>
</s-list-item>
</s-list>
</template>
<script setup lang="js">
import { ref } from 'vue'
import 'sard'
const current = ref(1)
const itemList = [{ name: '步骤1' }, { name: '步骤2' }, { name: '步骤3' }]
const prevStep = () => {
current.value = current.value <= 0 ? 3 : current.value - 1
}
const nextStep = () => {
current.value = current.value >= 3 ? 0 : current.value + 1
}
</script>当前步骤状态
可以设置当前处理中的步骤的状态为 finish 来模拟只有“未处理”和“已处理”两个状态的步骤条。
vue
<template>
<s-list card>
<s-list-item title="上一步" @click="prevStep" arrow hover />
<s-list-item title="下一步" @click="nextStep" arrow hover />
<s-list-item>
<s-steps :current="current" :item-list="itemList" direction="vertical" status="finish" />
</s-list-item>
</s-list>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { type StepsItem } from 'sard'
const current = ref(1)
const itemList: StepsItem[] = [
{ name: '订单已提交', description: '01月01日 12:00' },
{ name: '正在处理中', description: '01月01日 12:05' },
{ name: '订单已完成', description: '01月01日 12:10' },
]
const prevStep = () => {
current.value = current.value <= -1 ? 2 : current.value - 1
}
const nextStep = () => {
current.value = current.value >= 2 ? -1 : current.value + 1
}
</script>vue
<template>
<s-list card>
<s-list-item title="上一步" @click="prevStep" arrow hover />
<s-list-item title="下一步" @click="nextStep" arrow hover />
<s-list-item>
<s-steps :current="current" :item-list="itemList" direction="vertical" status="finish" />
</s-list-item>
</s-list>
</template>
<script setup lang="js">
import { ref } from 'vue'
import 'sard'
const current = ref(1)
const itemList = [
{
name: '订单已提交',
description: '01月01日 12:00',
},
{
name: '正在处理中',
description: '01月01日 12:05',
},
{
name: '订单已完成',
description: '01月01日 12:10',
},
]
const prevStep = () => {
current.value = current.value <= -1 ? 2 : current.value - 1
}
const nextStep = () => {
current.value = current.value >= 2 ? -1 : current.value + 1
}
</script>错误步骤
可以设置当前处理中的步骤的状态为 error 表示步骤运行错误。
vue
<template>
<s-list card>
<s-list-item title="上一步" @click="prevStep" arrow hover />
<s-list-item title="下一步" @click="nextStep" arrow hover />
<s-list-item>
<s-steps :current="current" :item-list="itemList" center status="error" />
</s-list-item>
</s-list>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { type StepsItem } from 'sard'
const current = ref(1)
const itemList: StepsItem[] = [{ name: '步骤1' }, { name: '步骤2' }, { name: '步骤3' }]
const prevStep = () => {
current.value = current.value <= 0 ? 3 : current.value - 1
}
const nextStep = () => {
current.value = current.value >= 3 ? 0 : current.value + 1
}
</script>vue
<template>
<s-list card>
<s-list-item title="上一步" @click="prevStep" arrow hover />
<s-list-item title="下一步" @click="nextStep" arrow hover />
<s-list-item>
<s-steps :current="current" :item-list="itemList" center status="error" />
</s-list-item>
</s-list>
</template>
<script setup lang="js">
import { ref } from 'vue'
import 'sard'
const current = ref(1)
const itemList = [{ name: '步骤1' }, { name: '步骤2' }, { name: '步骤3' }]
const prevStep = () => {
current.value = current.value <= 0 ? 3 : current.value - 1
}
const nextStep = () => {
current.value = current.value >= 3 ? 0 : current.value + 1
}
</script>自定义各步骤状态
每个步骤都可以使用 status 属性设置其状态。
vue
<template>
<s-list card>
<s-list-item>
<s-steps :item-list="itemList" direction="vertical" />
</s-list-item>
</s-list>
</template>
<script setup lang="ts">
import { type StepsItem } from 'sard'
const itemList: StepsItem[] = [
{ name: '第1节', description: '已学习', status: 'finish' },
{ name: '第2节', description: '学习中', status: 'process' },
{ name: '第3节', description: '未学习', status: 'wait' },
{ name: '第4节', description: '已学习', status: 'finish' },
{ name: '第5节', description: '出错了', status: 'error' },
]
</script>vue
<template>
<s-list card>
<s-list-item>
<s-steps :item-list="itemList" direction="vertical" />
</s-list-item>
</s-list>
</template>
<script setup lang="js">
import 'sard'
const itemList = [
{
name: '第1节',
description: '已学习',
status: 'finish',
},
{
name: '第2节',
description: '学习中',
status: 'process',
},
{
name: '第3节',
description: '未学习',
status: 'wait',
},
{
name: '第4节',
description: '已学习',
status: 'finish',
},
{
name: '第5节',
description: '出错了',
status: 'error',
},
]
</script>默认插槽
使用 Step 组件实现自定义内容,必须传递 index 属性。
vue
<template>
<s-list card>
<s-list-item title="上一步" @click="prevStep" arrow hover />
<s-list-item title="下一步" @click="nextStep" arrow hover />
<s-list-item>
<s-steps :current="current" direction="vertical">
<s-step v-for="(item, i) in itemList" :key="i" :index="i">
<div style="display: flex; align-items: center">
<div>
<div>{{ item.name }}</div>
<div style="color: var(--s-text-color-tertiary); font-size: var(--s-font-size-sm)">
{{ item.description }}
</div>
</div>
<s-button style="margin-inline-start: auto" variant="link">操作</s-button>
</div>
</s-step>
</s-steps>
</s-list-item>
</s-list>
</template>
<script setup lang="ts">
import { ref } from 'vue'
const current = ref(8)
const itemList = [
{ name: '步骤1', description: '这是描述' },
{ name: '步骤2', description: '这是描述' },
{ name: '步骤3', description: '这是描述' },
]
const prevStep = () => {
current.value = current.value <= 0 ? itemList.length : current.value - 1
}
const nextStep = () => {
current.value = current.value >= itemList.length ? 0 : current.value + 1
}
</script>vue
<template>
<s-list card>
<s-list-item title="上一步" @click="prevStep" arrow hover />
<s-list-item title="下一步" @click="nextStep" arrow hover />
<s-list-item>
<s-steps :current="current" direction="vertical">
<s-step v-for="(item, i) in itemList" :key="i" :index="i">
<div style="display: flex; align-items: center">
<div>
<div>{{ item.name }}</div>
<div style="color: var(--s-text-color-tertiary); font-size: var(--s-font-size-sm)">
{{ item.description }}
</div>
</div>
<s-button style="margin-inline-start: auto" variant="link">操作</s-button>
</div>
</s-step>
</s-steps>
</s-list-item>
</s-list>
</template>
<script setup lang="js">
import { ref } from 'vue'
const current = ref(8)
const itemList = [
{
name: '步骤1',
description: '这是描述',
},
{
name: '步骤2',
description: '这是描述',
},
{
name: '步骤3',
description: '这是描述',
},
]
const prevStep = () => {
current.value = current.value <= 0 ? itemList.length : current.value - 1
}
const nextStep = () => {
current.value = current.value >= itemList.length ? 0 : current.value + 1
}
</script>API
StepsProps
| 属性 | 描述 | 类型 | 默认值 |
|---|---|---|---|
| current | 当前步骤对应的索引值 | number | 0 |
| item-list | 所有步骤的数据 | StepsItem[] | [] |
| center | 是否居中 | boolean | false |
| direction | 排列方向 | 'vertical' | 'horizontal' | 'horizontal' |
| reverse | 水平排列时,文字和图标是否调换位置 | boolean | false |
| status | 指定当前步骤的状态 | StepsStatus | - |
StepsSlots
| 插槽 | 描述 | 属性 |
|---|---|---|
| default | 自定义默认内容 | - |
StepProps
| 属性 | 描述 | 类型 | 默认值 |
|---|---|---|---|
| status | 自定义状态 | StepsStatus | - |
| name | 步骤名称 | string | - |
| description | 步骤描述 | string | - |
| index | 步骤下标(必填) | number | - |
StepSlots
| 插槽 | 描述 | 属性 |
|---|---|---|
| default | 自定义默认内容 | { status: StepsStatus } |
| icon | 自定义图标内容 | { status: StepsStatus } |
StepsItem
| 属性 | 描述 | 类型 | 默认值 |
|---|---|---|---|
| status | 自定义状态 | StepsStatus | - |
| name | 步骤名称 | string | - |
| description | 步骤描述 | string | - |
StepsStatus
ts
type StepsStatus = 'wait' | 'process' | 'error' | 'finish'主题定制
样式变量
| CSS 变量 | 值 |
|---|---|
--s-steps-step-font-size | var(--s-font-size) |
--s-steps-step-opacity-active | var(--s-opacity-active) |
--s-steps-step-min-height | 36px |
--s-steps-icon-color-finish | var(--s-color-primary) |
--s-steps-icon-color-process | var(--s-color-primary) |
--s-steps-icon-color-wait | var(--s-text-color-tertiary) |
--s-steps-icon-color-error | var(--s-color-danger) |
--s-steps-text-color-finish | var(--s-text-color-primary) |
--s-steps-text-color-process | var(--s-color-primary) |
--s-steps-text-color-wait | var(--s-text-color-tertiary) |
--s-steps-text-color-error | var(--s-color-danger) |
--s-steps-header-padding-y | var(--s-size-2xs) |
--s-steps-header-padding-x | var(--s-size-sm) |
--s-steps-header-top-vertical | 4px |
--s-steps-line-thickness | 1px |
--s-steps-line-margin | 3px |
--s-steps-line-color | var(--s-border-color) |
--s-steps-line-color-active | var(--s-color-primary) |
--s-steps-icon-font-size | var(--s-font-size) |
--s-steps-body-padding-x | var(--s-size-xs) |
--s-steps-body-padding-y | var(--s-size-2xs) |
--s-steps-name-font-size | var(--s-font-size) |
--s-steps-description-margin-top | var(--s-size-2xs) |
--s-steps-description-font-size | var(--s-font-size-sm) |
--s-steps-description-color | var(--s-text-color-tertiary) |