改写自:Vue步骤条(Steps)_theMuseCatcher的博客-CSDN博客_vue 步骤条
因目前使用技术栈为vue3 所以稍作修改:
修改过程中的问题:
1. ref响应式失效:ref之后,不会对变量直接进行更改,需要.value
2. props中的数据可以直接在页面元素中使用
自定义封装步骤条:
<template>
<div class="m-steps-area">
<div class="m-steps">
<div
:class="['m-steps-item',
{ 'finished': current > n,
'process': current === n && n !== totalSteps,
'last-process': current === totalSteps && n === totalSteps,
'middle-wait': current < n && n !== totalSteps,
'last-wait': current < n && n === totalSteps,
}
]"
v-for="n in totalSteps"
:key="n"
@click="onChange(n)">
<div class="m-steps-icon">
<span class="u-icon">{{ current }}</span>
</div>
<div class="m-steps-content">
<div class="u-steps-title">{{ stepsLabel[n-1] || 'S ' + n }}</div>
<!-- <div class="u-steps-description">{{ stepsDesc[n-1] || 'Desc ' + n }}</div> -->
</div>
</div>
</div>
<el-button @click="onChange">下一步</el-button>
</div>
</template>
<script>
import { reactive, toRefs,ref } from 'vue'
export default {
props: {
stepsLabel: { // 步骤title数组
type: Array,
default: () => {
return []
}
},
stepsDesc: { // 步骤description数组
type: Array,
default: () => {
return []
}
},
totalSteps: { // 总的步骤数
type: Number,
default: 3
},
currentStep: { // 当前选中的步骤
type: Number,
default: 1
}
},
setup(prop){
let state = reactive({
})
let current = ref(1)
const onChange = ()=>{ // 点击切换选择步骤
// if (state.current < prop.totalSteps) {
// // console.log(state.current)
// state.current++
// }else {
// state.current = 1
// }
if (current.value < prop.totalSteps) {
// console.log(current)
current.value++
}else {
// console.log('ll',current)
current.value = 1
}
}
return {
...toRefs(state),
current,
onChange
}
}
}
</script>
<style lang="scss" scoped>
.m-steps-area {
width: 900px;
margin: 0px auto;
.m-steps {
padding: 30px 0;
display: flex;
.m-steps-item {
display: inline-block;
flex: 1; // 弹性盒模型对象的子元素都有相同的长度,且忽略它们内部的内容
text-align: left;
overflow: hidden;
font-size: 16px;
line-height: 32px;
.m-steps-icon {
display: inline-block;
margin-right: 8px;
width: 32px;
height: 32px;
border-radius: 50%;
text-align: center;
}
.m-steps-content {
display: inline-block;
vertical-align: top;
padding-right: 10px;
.u-steps-title {
position: relative;
display: inline-block;
padding-right: 16px;
}
.u-steps-description {
font-size: 14px;
max-width: 140px;
}
}
}
.finished {
margin-right: 16px;
cursor: pointer;
// &:hover {
// .m-steps-content {
// .u-steps-title {
// color: #1890ff;
// }
// .u-steps-description {
// color: #1890ff;
// }
// }
// }
.m-steps-icon {
background: #1890ff;
border: 1px solid rgba(0,0,0,.25);
border-color: #1890ff;
.u-icon {
color: #fff;
}
}
.m-steps-content {
color: rgba(0,0,0,.65);
.u-steps-title {
color: rgba(0,0,0,.65);
&:after {
background: #1890ff;
position: absolute;
top: 16px;
left: 100%;
display: block;
width: 9999px;
height: 1px;
content: "";
}
}
// .u-steps-description {
// color: rgba(17, 153, 67, 0.45);
// }
}
}
.process {
margin-right: 16px;
.m-steps-icon {
background: #1890ff;
border: 1px solid rgba(0,0,0,.25);
border-color: #1890ff;
.u-icon {
color: #fff;
}
}
.m-steps-content {
color: rgba(0,0,0,.65);
.u-steps-title {
color: rgba(0,0,0,.85);
&:after {
background: #e8e8e8;
position: absolute;
top: 16px;
left: 100%;
display: block;
width: 9999px;
height: 1px;
content: "";
}
}
.u-steps-description {
color: rgba(0,0,0,.65);
}
}
}
.last-process {
margin-right: 0;
.m-steps-icon {
background: #1890ff;
border: 1px solid rgba(0,0,0,.25);
border-color: #1890ff;
.u-icon {
color: #fff;
}
}
.m-steps-content {
color: rgba(0,0,0,.65);
.u-steps-title {
color: rgba(0,0,0,.85);
}
.u-steps-description {
color: rgba(0,0,0,.65);
}
}
}
.middle-wait {
margin-right: 16px;
cursor: pointer;
&:hover {
.m-steps-icon {
border: 1px solid #1890ff;
.u-icon {
color: #1890ff;
}
}
.m-steps-content {
.u-steps-title {
color: #1890ff;
}
.u-steps-description {
color: #1890ff;
}
}
}
.m-steps-icon {
background: #fff;
border: 1px solid rgba(0,0,0,.25);
.u-icon {
color: rgba(0,0,0,.25);
}
}
.m-steps-content {
color: rgba(0,0,0,.65);
.u-steps-title {
color: rgba(0,0,0,.45);
&:after {
background: #e8e8e8;
position: absolute;
top: 16px;
left: 100%;
display: block;
width: 9999px;
height: 1px;
content: "";
}
}
.u-steps-description {
color: rgba(0,0,0,.45);
}
}
}
.last-wait {
margin-right: 0;
cursor: pointer;
&:hover {
.m-steps-icon {
border: 1px solid #1890ff;
.u-icon {
color: #1890ff;
}
}
.m-steps-content {
.u-steps-title {
color: #1890ff;
}
.u-steps-description {
color: #1890ff;
}
}
}
.m-steps-icon {
background: #fff;
border: 1px solid rgba(0,0,0,.25);
.u-icon {
color: rgba(0,0,0,.25);
}
}
.m-steps-content {
color: rgba(0,0,0,.65);
.u-steps-title {
color: rgba(0,0,0,.45);
}
.u-steps-description {
color: rgba(0,0,0,.45);
}
}
}
}
}
</style>
引用步骤条组件:
<template>
<div class="index">
<Steps :currentStep="1" :totalSteps="6" :stepsLabel="stepsLabel" :stepsDesc="stepsDesc" />
</div>