介绍
引导用户按照流程完成任务的分步导航条。
引入
js
import Steps from 'sard-uniapp/components/steps/steps.vue'代码演示
基础使用
使用 current 属性指定步骤的下标,小于这个下标的步骤状态为 finish,等于这个下标的步骤状态为 process,大于这个下标的步骤状态为 wait。
vue
<template>
<sar-list card>
<sar-list-item title="上一步" @click="prevStep" arrow hover />
<sar-list-item title="下一步" @click="nextStep" arrow hover />
<sar-list-item>
<sar-steps :current="current" :item-list="itemList" />
</sar-list-item>
</sar-list>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { type StepsItem } from 'sard-uniapp'
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>
<sar-list card>
<sar-list-item title="上一步" @click="prevStep" arrow hover />
<sar-list-item title="下一步" @click="nextStep" arrow hover />
<sar-list-item>
<sar-steps :current="current" :item-list="itemList" />
</sar-list-item>
</sar-list>
</template>
<script setup lang="js">
import { ref } from "vue";
const current = ref(1);
const itemList = [
{ name: "\u6B65\u9AA41" },
{ name: "\u6B65\u9AA42" },
{ name: "\u6B65\u9AA43" }
];
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>
<sar-list card>
<sar-list-item title="上一步" @click="prevStep" arrow hover />
<sar-list-item title="下一步" @click="nextStep" arrow hover />
<sar-list-item>
<sar-steps :current="current" center :item-list="itemList" />
</sar-list-item>
</sar-list>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { type StepsItem } from 'sard-uniapp'
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>
<sar-list card>
<sar-list-item title="上一步" @click="prevStep" arrow hover />
<sar-list-item title="下一步" @click="nextStep" arrow hover />
<sar-list-item>
<sar-steps :current="current" center :item-list="itemList" />
</sar-list-item>
</sar-list>
</template>
<script setup lang="js">
import { ref } from "vue";
const current = ref(1);
const itemList = [
{ name: "\u6B65\u9AA41" },
{ name: "\u6B65\u9AA42" },
{ name: "\u6B65\u9AA43" }
];
const prevStep = () => {
current.value = current.value <= 0 ? 3 : current.value - 1;
};
const nextStep = () => {
current.value = current.value >= 3 ? 0 : current.value + 1;
};
</script>文字在上 1.23.4+
可以使用 reverse 属性将水平排列时的文字和图标位置调换。
vue
<template>
<sar-list card>
<sar-list-item title="上一步" @click="prevStep" arrow hover />
<sar-list-item title="下一步" @click="nextStep" arrow hover />
<sar-list-item>
<sar-steps :current="current" reverse :item-list="itemList" />
</sar-list-item>
</sar-list>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { type StepsItem } from 'sard-uniapp'
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>
<sar-list card>
<sar-list-item title="上一步" @click="prevStep" arrow hover />
<sar-list-item title="下一步" @click="nextStep" arrow hover />
<sar-list-item>
<sar-steps :current="current" reverse :item-list="itemList" />
</sar-list-item>
</sar-list>
</template>
<script setup lang="js">
import { ref } from "vue";
const current = ref(1);
const itemList = [
{ name: "\u6B65\u9AA41" },
{ name: "\u6B65\u9AA42" },
{ name: "\u6B65\u9AA43" }
];
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>
<sar-list card>
<sar-list-item title="上一步" @click="prevStep" arrow hover />
<sar-list-item title="下一步" @click="nextStep" arrow hover />
<sar-list-item>
<sar-steps
:current="current"
:item-list="itemList"
direction="vertical"
/>
</sar-list-item>
</sar-list>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { type StepsItem } from 'sard-uniapp'
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>
<sar-list card>
<sar-list-item title="上一步" @click="prevStep" arrow hover />
<sar-list-item title="下一步" @click="nextStep" arrow hover />
<sar-list-item>
<sar-steps
:current="current"
:item-list="itemList"
direction="vertical"
/>
</sar-list-item>
</sar-list>
</template>
<script setup lang="js">
import { ref } from "vue";
const current = ref(1);
const itemList = [
{ name: "\u6B65\u9AA41", description: "\u8FD9\u662F\u63CF\u8FF0" },
{ name: "\u6B65\u9AA42", description: "\u8FD9\u662F\u63CF\u8FF0" },
{ name: "\u6B65\u9AA43", description: "\u8FD9\u662F\u63CF\u8FF0" }
];
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>
<sar-list card>
<sar-list-item title="上一步" @click="prevStep" arrow hover />
<sar-list-item title="下一步" @click="nextStep" arrow hover />
<sar-list-item>
<sar-steps
:current="current"
:item-list="itemList"
direction="vertical"
center
/>
</sar-list-item>
</sar-list>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { type StepsItem } from 'sard-uniapp'
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>
<sar-list card>
<sar-list-item title="上一步" @click="prevStep" arrow hover />
<sar-list-item title="下一步" @click="nextStep" arrow hover />
<sar-list-item>
<sar-steps
:current="current"
:item-list="itemList"
direction="vertical"
center
/>
</sar-list-item>
</sar-list>
</template>
<script setup lang="js">
import { ref } from "vue";
const current = ref(1);
const itemList = [
{ name: "\u6B65\u9AA41", description: "\u8FD9\u662F\u63CF\u8FF0" },
{ name: "\u6B65\u9AA42", description: "\u8FD9\u662F\u63CF\u8FF0" },
{ name: "\u6B65\u9AA43", description: "\u8FD9\u662F\u63CF\u8FF0" }
];
const prevStep = () => {
current.value = current.value <= 0 ? 3 : current.value - 1;
};
const nextStep = () => {
current.value = current.value >= 3 ? 0 : current.value + 1;
};
</script>自定义图标
使用 finishIcon, processIcon, waitIcon, errorIcon 属性设置不通状态下的图标。
vue
<template>
<sar-list card>
<sar-list-item title="上一步" @click="prevStep" arrow hover />
<sar-list-item title="下一步" @click="nextStep" arrow hover />
<sar-list-item>
<sar-steps
:current="current"
:item-list="itemList"
center
finish-icon="star-fill"
process-icon="star"
wait-icon="star"
icon-size="40rpx"
/>
</sar-list-item>
</sar-list>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { type StepsItem } from 'sard-uniapp'
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>
<sar-list card>
<sar-list-item title="上一步" @click="prevStep" arrow hover />
<sar-list-item title="下一步" @click="nextStep" arrow hover />
<sar-list-item>
<sar-steps
:current="current"
:item-list="itemList"
center
finish-icon="star-fill"
process-icon="star"
wait-icon="star"
icon-size="40rpx"
/>
</sar-list-item>
</sar-list>
</template>
<script setup lang="js">
import { ref } from "vue";
const current = ref(1);
const itemList = [
{ name: "\u6B65\u9AA41" },
{ name: "\u6B65\u9AA42" },
{ name: "\u6B65\u9AA43" }
];
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>
<sar-list card>
<sar-list-item title="上一步" @click="prevStep" arrow hover />
<sar-list-item title="下一步" @click="nextStep" arrow hover />
<sar-list-item>
<sar-steps
:current="current"
:item-list="itemList"
center
root-style="--sar-steps-icon-finish-color: var(--sar-orange);
--sar-steps-icon-process-color: var(--sar-orange);
--sar-steps-text-process-color: var(--sar-orange);
--sar-steps-line-active-color: var(--sar-orange)"
/>
</sar-list-item>
</sar-list>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { type StepsItem } from 'sard-uniapp'
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>
<sar-list card>
<sar-list-item title="上一步" @click="prevStep" arrow hover />
<sar-list-item title="下一步" @click="nextStep" arrow hover />
<sar-list-item>
<sar-steps
:current="current"
:item-list="itemList"
center
root-style="--sar-steps-icon-finish-color: var(--sar-orange);
--sar-steps-icon-process-color: var(--sar-orange);
--sar-steps-text-process-color: var(--sar-orange);
--sar-steps-line-active-color: var(--sar-orange)"
/>
</sar-list-item>
</sar-list>
</template>
<script setup lang="js">
import { ref } from "vue";
const current = ref(1);
const itemList = [
{ name: "\u6B65\u9AA41" },
{ name: "\u6B65\u9AA42" },
{ name: "\u6B65\u9AA43" }
];
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>
<sar-list card>
<sar-list-item title="上一步" @click="prevStep" arrow hover />
<sar-list-item title="下一步" @click="nextStep" arrow hover />
<sar-list-item>
<sar-steps
:current="current"
:item-list="itemList"
direction="vertical"
status="finish"
/>
</sar-list-item>
</sar-list>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { type StepsItem } from 'sard-uniapp'
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>
<sar-list card>
<sar-list-item title="上一步" @click="prevStep" arrow hover />
<sar-list-item title="下一步" @click="nextStep" arrow hover />
<sar-list-item>
<sar-steps
:current="current"
:item-list="itemList"
direction="vertical"
status="finish"
/>
</sar-list-item>
</sar-list>
</template>
<script setup lang="js">
import { ref } from "vue";
const current = ref(1);
const itemList = [
{ name: "\u8BA2\u5355\u5DF2\u63D0\u4EA4", description: "01\u670801\u65E5 12:00" },
{ name: "\u6B63\u5728\u5904\u7406\u4E2D", description: "01\u670801\u65E5 12:05" },
{ name: "\u8BA2\u5355\u5DF2\u5B8C\u6210", description: "01\u670801\u65E5 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>
<sar-list card>
<sar-list-item title="上一步" @click="prevStep" arrow hover />
<sar-list-item title="下一步" @click="nextStep" arrow hover />
<sar-list-item>
<sar-steps
:current="current"
:item-list="itemList"
center
status="error"
/>
</sar-list-item>
</sar-list>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { type StepsItem } from 'sard-uniapp'
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>
<sar-list card>
<sar-list-item title="上一步" @click="prevStep" arrow hover />
<sar-list-item title="下一步" @click="nextStep" arrow hover />
<sar-list-item>
<sar-steps
:current="current"
:item-list="itemList"
center
status="error"
/>
</sar-list-item>
</sar-list>
</template>
<script setup lang="js">
import { ref } from "vue";
const current = ref(1);
const itemList = [
{ name: "\u6B65\u9AA41" },
{ name: "\u6B65\u9AA42" },
{ name: "\u6B65\u9AA43" }
];
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>
<sar-list card>
<sar-list-item>
<sar-steps :item-list="itemList" direction="vertical" />
</sar-list-item>
</sar-list>
</template>
<script setup lang="ts">
import { type StepsItem } from 'sard-uniapp'
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>
<sar-list card>
<sar-list-item>
<sar-steps :item-list="itemList" direction="vertical" />
</sar-list-item>
</sar-list>
</template>
<script setup lang="js">
const itemList = [
{ name: "\u7B2C1\u8282", description: "\u5DF2\u5B66\u4E60", status: "finish" },
{ name: "\u7B2C2\u8282", description: "\u5B66\u4E60\u4E2D", status: "process" },
{ name: "\u7B2C3\u8282", description: "\u672A\u5B66\u4E60", status: "wait" },
{ name: "\u7B2C4\u8282", description: "\u5DF2\u5B66\u4E60", status: "finish" },
{ name: "\u7B2C5\u8282", description: "\u51FA\u9519\u4E86", status: "error" }
];
</script>默认插槽
版本 1.17.1+ 可使用 Step 组件实现自定义内容,必须传递 index 属性。
vue
<template>
<sar-list card>
<sar-list-item title="上一步" @click="prevStep" arrow hover />
<sar-list-item title="下一步" @click="nextStep" arrow hover />
<sar-list-item>
<sar-steps :current="current" direction="vertical">
<sar-step v-for="(item, i) in itemList" :key="i" :index="i">
<view style="display: flex; align-items: center">
<view>
<view>{{ item.name }}</view>
<view
style="
color: var(--sar-tertiary-color);
font-size: var(--sar-text-sm);
"
>
{{ item.description }}
</view>
</view>
<sar-button root-style="margin-left: auto" inline type="pale-text">
操作
</sar-button>
</view>
</sar-step>
</sar-steps>
</sar-list-item>
</sar-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>
<sar-list card>
<sar-list-item title="上一步" @click="prevStep" arrow hover />
<sar-list-item title="下一步" @click="nextStep" arrow hover />
<sar-list-item>
<sar-steps :current="current" direction="vertical">
<sar-step v-for="(item, i) in itemList" :key="i" :index="i">
<view style="display: flex; align-items: center">
<view>
<view>{{ item.name }}</view>
<view
style="
color: var(--sar-tertiary-color);
font-size: var(--sar-text-sm);
"
>
{{ item.description }}
</view>
</view>
<sar-button root-style="margin-left: auto" inline type="pale-text">
操作
</sar-button>
</view>
</sar-step>
</sar-steps>
</sar-list-item>
</sar-list>
</template>
<script setup lang="js">
import { ref } from "vue";
const current = ref(8);
const itemList = [
{ name: "\u6B65\u9AA41", description: "\u8FD9\u662F\u63CF\u8FF0" },
{ name: "\u6B65\u9AA42", description: "\u8FD9\u662F\u63CF\u8FF0" },
{ name: "\u6B65\u9AA43", description: "\u8FD9\u662F\u63CF\u8FF0" }
];
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
| 属性 | 描述 | 类型 | 默认值 |
|---|---|---|---|
| root-class | 组件根元素类名 | string | - |
| root-style | 组件根元素样式 | StyleValue | - |
| current | 当前步骤对应的索引值 | number | 0 |
| item-list | 所有步骤的数据 | StepsItem[] | [] |
| center | 是否居中 | boolean | false |
| direction | 排列方向 | 'vertical' | 'horizontal' | 'horizontal' |
| reverse | 水平排列时,文字和图标是否调换位置 | boolean | false |
| status | 指定当前步骤的状态 | StepsStatus | - |
| icon-family | 图标字体 | string | - |
| icon-size | 图标字号 | string | - |
| finish-icon | 已完成状态的图标名称 | string | - |
| process-icon | 处理中状态的图标名称 | string | - |
| wait-icon | 等待中状态的图标名称 | string | - |
| error-icon | 错误状态的图标名称 | string | - |
StepsSlots
| 插槽 | 描述 | 属性 |
|---|---|---|
| default | 自定义默认内容 | - |
StepProps
| 属性 | 描述 | 类型 | 默认值 |
|---|---|---|---|
| root-class | 组件根元素类名 | string | - |
| root-style | 组件根元素样式 | StyleValue | - |
| 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 变量
scss
page,
.sar-portal {
--sar-steps-step-font-size: var(--sar-text-base);
--sar-steps-step-active-opacity: var(--sar-active-opacity);
--sar-steps-step-min-height: 72rpx;
--sar-steps-icon-finish-color: var(--sar-primary);
--sar-steps-icon-process-color: var(--sar-primary);
--sar-steps-icon-wait-color: var(--sar-tertiary-color);
--sar-steps-icon-error-color: var(--sar-danger);
--sar-steps-text-finish-color: var(--sar-body-color);
--sar-steps-text-process-color: var(--sar-primary);
--sar-steps-text-wait-color: var(--sar-tertiary-color);
--sar-steps-text-error-color: var(--sar-danger);
--sar-steps-header-gap-y: 8rpx;
--sar-steps-header-gap-x: 24rpx;
--sar-steps-header-vertical-top: 8rpx;
--sar-steps-line-thickness: 1px;
--sar-steps-line-gap: 6rpx;
--sar-steps-line-color: var(--sar-border-color);
--sar-steps-line-active-color: var(--sar-primary);
--sar-steps-icon-font-size: var(--sar-text-base);
--sar-steps-body-padding-x: 16rpx;
--sar-steps-body-padding-y: 8rpx;
--sar-steps-name-font-size: var(--sar-text-base);
--sar-steps-description-margin-top: 8rpx;
--sar-steps-description-font-size: var(--sar-text-sm);
--sar-steps-description-color: var(--sar-tertiary-color);
}