html
<template>
<div class="main">
<div class="steps">
<ol>
<li
v-for="(step, index) in steps"
:key="index"
:class="{ active: currentIndex === index, done: currentIndex > index }"
>
{{ step }}
</li>
</ol>
</div>
<div class="step-content">
<div v-if="currentIndex === 0">
<h3>账号验证</h3>
<p>请填写您的账号。</p>
<input/>
<button @click="nextStep" :disabled="currentIndex === steps.length - 1">下一步</button>
</div>
<div v-else-if="currentIndex === 1">
<h3>身份校验</h3>
<p>请输入您的身份信息进行校验。</p>
<input/>
<button @click="nextStep" :disabled="currentIndex === steps.length - 1">下一步</button>
</div>
<div v-else-if="currentIndex === 2">
<h3>验证码校验</h3>
<p>请输入您收到的验证码进行校验。</p>
<input/>
<button @click="nextStep" :disabled="currentIndex === steps.length - 1">下一步</button>
</div>
<div v-else-if="currentIndex === 3">
<h3>密码重置</h3>
<p>请输入您的新密码进行重置。</p>
<input/>
<button @click="nextStep" :disabled="currentIndex === steps.length - 1">修改密码</button>
</div>
</div>
<div class="step-button">
<button @click="prevStep" :disabled="currentIndex === 0">上一步</button>
</div>
</div>
</template>
<script setup>
import { ref } from 'vue';
const steps = ['找回账号', '身份校验', '验证码校验', '密码重置'];
const currentIndex = ref(0); // 当前活动步骤的索引
const nextStep = () => {
if (currentIndex.value < steps.length - 1) {
currentIndex.value++;
}
};
const prevStep = () => {
if (currentIndex.value > 0) {
currentIndex.value--;
}
};
</script>
<style scoped>
*{
padding: 0;
margin: 0;
}
/**/
.main{
display: flex;
flex-direction: column;
align-items: center;
}
.step-content{
margin-top: 10vh; /* 与步骤条的垂直距离 */
text-align: center; /* 水平居中文本 */
}
.step-content p,
.step-content h1,
.step-content input{
margin-top: 3vh;
}
.step-button{
margin-top: 2vh;
}
/* step步骤条核心样式 */
.steps ol {
--normal-color: #fff; /* css变量,默认颜色 */
--active-color: #428aea; /* css变量,激活颜色 */
display: flex;
width: 70vw;
margin-top: 15%; /* 调整步骤条垂直位置 */
justify-content: space-between;
counter-reset: order; /* 定义CSS计数器 */
}
/* 步骤项 */
.steps ol > li {
flex: auto;
display: inline-flex;
align-items: center;
counter-increment: order;
color: var(--active-color);
}
/* 去掉右边多余 */
.steps ol > li:last-child {flex: none;}
/* 步骤编号(带圈数字) */
.steps ol> li::before {
content: counter(order);
flex-shrink: 0;
width: 1.4em;
line-height: 1.4em;
margin-right: .5em;
text-align: center;
border-radius: 50%;
border: 1px solid;
}
/* 步骤项引导线 */
.steps ol> li:not(:last-child)::after {
content: '';
flex: 1;
margin: 0 1em;
border-bottom: 1px solid;
opacity: .6;
}
/* 步骤状态 */
.steps ol> .active {color: var(--active-color);}
.steps ol> .active::before {
color: #fff;
background: var(--active-color);
border-color: var(--active-color);
}
.steps ol> .active::after,
.steps ol> .active ~ li {color: var(--normal-color);}
</style>
基于vue3的抽象组件

