背景
elementUi步骤条组件中的文字总是在icon下边显示,我们的UI设计稿中的步骤条的文字在icon右边,UI同学坚持这样设计,所以只能手写了
效果预览
代码展示
<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" v-if="current<=n">{{ n }}</span>
<span class="el-icon-check u-icon" v-else></span>
<!-- <span class="el-icon-check u-icon" v-else>✓</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] }}</div>
<!-- <div class="u-steps-description">{{ stepsDesc[n-1] || 'Desc ' + n }}</div> -->
</div>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'aSteps',
props: {
stepsLabel: { // 步骤title数组
type: Array,
default: () => {
return []
}
},
stepsDesc: { // 步骤description数组
type: Array,
default: () => {
return []
}
},
totalSteps: { // 总的步骤数
type: Number,
default: 3
},
currentStep: { // 当前选中的步骤
type: Number,
default: 1
}
},
data () {
return {
// 若当前选中步骤超过总步骤数,则默认选择步骤1
current: this.currentStep > this.totalSteps ? 1 : this.currentStep
}
},
methods: {
onChange (index) { // 点击切换选择步骤
//console.log('index:', index)
// if (this.current !== index) {
// this.current = index
// this.$emit('change', index)
// }
}
}
}
</script>
<style lang="scss" scoped>
$steps-color: #03B955;
.m-steps-area {
width: 100%;
margin: 0px auto;
.m-steps {
padding: 30px 0;
display: flex;
.m-steps-item {
display: inline-block;
flex: 1; // 弹性盒模型对象的子元素都有相同的长度,且忽略它们内部的内容
flex-wrap: nowrap;
white-space: nowrap;
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: 16px;
.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: $steps-color;
}
.u-steps-description {
//color: $steps-color;
}
}
}
.m-steps-icon {
background: #fff;
border: 1px solid rgba(0,0,0,.25);
border-color: $steps-color;
.u-icon {
color: $steps-color;
}
}
.m-steps-content {
color: rgba(0,0,0,.65);
.u-steps-title {
color: rgba(0,0,0,.65);
&:after {
background: $steps-color;
position: absolute;
top: 16px;
left: 100%;
display: block;
width: 9999px;
height: 1px;
content: "";
}
}
.u-steps-description {
color: rgba(0,0,0,.45);
}
}
}
.process {
margin-right: 16px;
.m-steps-icon {
background: $steps-color;
border: 1px solid rgba(0,0,0,.25);
border-color: $steps-color;
.u-icon {
color: #fff;
}
}
.m-steps-content {
color: rgba(0,0,0,.65);
.u-steps-title {
font-weight: 600;
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: $steps-color;
border: 1px solid rgba(0,0,0,.25);
border-color: $steps-color;
.u-icon {
color: #fff;
}
}
.m-steps-content {
color: rgba(0,0,0,.65);
.u-steps-title {
font-weight: 600;
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 $steps-color;
.u-icon {
// color: $steps-color;
}
}
.m-steps-content {
.u-steps-title {
// color: $steps-color;
}
.u-steps-description {
// color: $steps-color;
}
}
}
.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 $steps-color;
.u-icon {
// color: $steps-color;
}
}
.m-steps-content {
.u-steps-title {
//@debug color: $steps-color;
}
.u-steps-description {
// color: $steps-color;
}
}
}
.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>
开始使用
import Steps from '@/components/steps.vue'
components: {
Steps
},
current: 2,
stepsLabel: ['步骤1', '步骤2', '步骤3'],
stepsDesc: ['描述1','描述2','描述3'],
<Steps :currentStep="current" :totalSteps="stepsLabel.length" :stepsLabel="stepsLabel" :stepsDesc="stepsDesc" @change="onChange" />
onChange(current) {
console.log('onChange:', current);
this.current = current;
}
写在最后
有问题欢迎留言,随时解答