Vue3步骤条(Steps) Vue2步骤条Steps可自定义设置以下属性步骤数组items类型Item[]默认 []步骤条总宽度width类型number | string单位 px默认 auto步骤条大小size类型default | small默认 default是否使用垂直步骤条vertical当 vertical: true 时labelPlacement 自动设为 right类型boolean默认 false标签放置位置labelPlacement默认放图标右侧可选 bottom 放图标下方类型right | bottom默认 right是否使用点状步骤条dotted当 dotted: true 且 vertical: false 时labelPlacement 将自动设为 bottom类型boolean默认 false当前选中的步骤设置 v-model 后Steps 变为可点击状态v-model:current类型number默认 1从 1 开始计数效果如下图在线预览①创建步骤条组件Steps.vue其中引入使用了以下工具函数获取依赖注入 useInjectscript setup langts import { computed } from vue import { useInject } from components/utils export interface Item { title?: string // 标题 description?: string // 描述 } export interface Props { items?: Item[] // 步骤数组 width?: number | string // 步骤条总宽度单位 px size?: default | small // 步骤条大小 vertical?: boolean // 是否使用垂直步骤条当 vertical: true 时labelPlacement 自动设为 right labelPlacement?: right | bottom // 标签放置位置默认放图标右侧可选 bottom 放图标下方 dotted?: boolean // 是否使用点状步骤条当 dotted: true 且 vertical: false 时labelPlacement 将自动设为 bottom current?: number // (v-model) 当前选中的步骤设置 v-model 后Steps 变为可点击状态。从 1 开始计数 } const props withDefaults(definePropsProps(), { items: () [], width: auto, size: default, vertical: false, labelPlacement: right, dotted: false, current: 1 }) const { colorPalettes } useInject(Steps) // 主题色注入 const emits defineEmits([update:current, change]) const totalWidth computed(() { if (typeof props.width number) { return ${props.width}px } else { return props.width } }) // 步骤总数 const totalSteps computed(() { return props.items.length }) const currentStep computed(() { if (props.current 1) { return 1 } else if (props.current totalSteps.value 1) { return totalSteps.value 1 } else { return props.current } }) // 点击切换选择步骤 function onChange(index: number): void { if (currentStep.value ! index) { emits(update:current, index) emits(change, index) } } /script template div classsteps-wrap :class{ steps-small: size small, steps-vertical: vertical, steps-label-bottom: !vertical (labelPlacement bottom || dotted), steps-dotted: dotted } :style --steps-width: ${totalWidth}; --steps-primary-color: ${colorPalettes[5]}; --steps-primary-color-hover: ${colorPalettes[5]}; --steps-icon-color: ${colorPalettes[0]}; --steps-icon-color-hover: ${colorPalettes[5]}; div classsteps-item :class{ steps-finish: currentStep index 1, steps-process: currentStep index 1, steps-wait: currentStep index 1 } v-for(item, index) in items :keyindex div tabindex0 classsteps-info-wrap clickonChange(index 1) div classsteps-tail/div div classsteps-icon template v-if!dotted span v-ifcurrentStep index 1 classsteps-num{{ index 1 }}/span svg v-else classicon-svg focusablefalse >script setup langts import Steps from ./Steps.vue import { ref, watchEffect, reactive } from vue import type { StepsProps, StepsItem } from vue-amazing-ui const stepsItems refStepsItem[]([ { title: Step 1, description: description 1 }, { title: Step 2, description: description 2 }, { title: Step 3, description: description 3 }, { title: Step 4, description: description 4 }, { title: Step 5, description: description 5 } ]) const minStepsItems refStepsItem[]([ { title: Step 1 }, { title: Step 2 }, { title: Step 3 }, { title: Step 4 }, { title: Step 5 } ]) const current ref(3) watchEffect(() { console.log(current, current.value) }) const sizeOptions [ { label: default, value: default }, { label: small, value: small } ] const size ref(small) const placeOptions [ { label: right, value: right }, { label: bottom, value: bottom } ] const place ref(bottom) function onChange(index: number) { // 父组件获取切换后的选中步骤 console.log(change, index) } function onPrev() { if (current.value 1) { current.value-- } } function onNext() { if (stepsItems.value.length current.value) { current.value } } const state reactiveStepsProps({ size: default, vertical: false, labelPlacement: right, dotted: false, current: 3 }) /script template div h1{{ $route.name }} {{ $route.meta.title }}/h1 h2 classmt30 mb10基本使用/h2 Steps :itemsstepsItems :currentcurrent changeonChange / h2 classmt30 mb10标签放置位置/h2 Flex vertical Radio :optionsplaceOptions v-model:valueplace button button-stylesolid / Steps :itemsstepsItems :label-placementplace :currentcurrent / /Flex h2 classmt30 mb10迷你版/h2 Flex vertical Radio :optionssizeOptions v-model:valuesize button button-stylesolid / Steps :itemsminStepsItems :sizesize :currentcurrent / /Flex h2 classmt30 mb10垂直步骤条/h2 Space :gap120 Steps :itemsstepsItems vertical :currentcurrent / Steps :itemsstepsItems vertical sizesmall :currentcurrent / /Space h2 classmt30 mb10点状步骤条/h2 Space vertical Steps :itemsstepsItems dotted v-model:currentcurrent / Steps :itemsstepsItems vertical dotted v-model:currentcurrent / /Space h2 classmt30 mb10可点击/h2 h3 classmb10设置 v-model:current 后即可点击/h3 Flex vertical Space Button clickonPrevPrev/Button Button clickonNextNext/Button /Space Steps :itemsstepsItems v-model:currentcurrent / Steps :itemsstepsItems vertical v-model:currentcurrent / /Flex h2 classmt30 mb10步骤条配置器/h2 Row :gutter24 Col :span6 Space gapsmall vertical size: Radio :optionssizeOptions v-model:valuestate.size button button-stylesolid / /Space /Col Col :span6 Space gapsmall vertical vertical: Switch v-modelstate.vertical / /Space /Col Col :span6 Space gapsmall vertical labelPlacement: Radio :optionsplaceOptions v-model:valuestate.labelPlacement button button-stylesolid / /Space /Col Col :span6 Space gapsmall vertical dotted: Switch v-modelstate.dotted / /Space /Col /Row Steps classmt30 :itemsstepsItems :sizestate.size :verticalstate.vertical :label-placementstate.labelPlacement :dottedstate.dotted v-model:currentcurrent / /div /template