要求
element-plus 组件库中的步骤条不满足UI设计稿
UI设计稿的样式antd是可以实现的,但是目前开发项目中用的是vue+element
所以自己写了个横向步骤条组件,实现该功能
UI样式
组件应用
<RowSteps :active="step" :list="stepList" />
const stepList = reactive([
{ step: 1, text: '接口基本设置', sucess: false },
{ step: 2, text: '选择交易流程 ', sucess: false },
{ step: 3, text: '完成', sucess: false },
]);
const step = ref(1);
/取消 和 上一步
const handleCancel = (formEl) => {
if (!formEl) return;
if (step.value === 1) {
//取消
formEl.resetFields();
props.onClose();
} else if (step.value === 2) {
//上一步
step.value = 1;
delete rules.flowCode;
}
};
//确定表单验证 下一步 和提交
const handleConfirm = async (formEl) => {
if (!formEl) return;
await formEl.validate((valid, fields) => {
if (valid) {
if (step.value === 1) {
//点击下一步
step.value = 2;
//添加第二页的校验
rules.flowCode = [
{
required: true,
message: '请选择交易流程',
trigger: 'change',
},
];
} else if (step.value === 2) {
//提交
submitLoading.value = true;
handleSignIn();
// //第三步 提交成功后再到第三步
// step.value = 3;
}
} else {
console.log('error submit!', fields);
}
});
};
组件代码
<!--
* @Author: SunnyYang
* @Date: 2024-01-20 18:00:48
* @LastEditors: SunnyYang
* @LastEditTime: 2024-03-02 19:50:53
* @Description:
-->
<template>
<div class="form-step-box">
<div class="step-item" v-for="(item, index) in stepList" :key="item.step">
<el-icon v-if="status === 'icon' && item.success" class="success-icon-num"><CircleCheck /></el-icon>
<span v-else :class="['num', item.step === activeValue && 'active-num', item.success && 'success-num']">
{{ item.step }}
</span>
<span :class="['text', item.step <= activeValue ? 'active-text' : '']">{{ item.text }}</span>
<span v-if="index + 1 !== stepList.length" :class="['line', item.step < activeValue && 'active-line']"></span>
</div>
</div>
</template>
<script setup name='RowSteps'>
import { ref, watch } from 'vue';
const props = defineProps({
// 步骤条数据
list: {
type: Array,
default: () => [
// { step: 1, text: '接口基本设置', success: false }
],
},
active: {
type: Number,
default: 1,
},
status: {
type: String,
default: 'icon', //icon对勾 text数字
},
});
const activeValue = ref(props.active),
stepList = ref(props.list);
watch(
() => props.active,
() => {
activeValue.value = props.active;
//修改step
stepList.value = stepList.value.map((v) => ({ ...v, success: v.step < activeValue.value }));
},
);
</script>
<style lang="scss" scoped>
.form-step-box {
margin: 0 auto;
display: flex;
align-items: center;
justify-content: center;
.step-item {
display: inline-flex;
align-items: center;
flex-direction: row;
}
.num {
width: 24px;
height: 24px;
border-radius: 50%;
display: flex;
justify-content: center;
align-items: center;
margin: 0 10px;
font-family: PingFang SC, PingFang SC;
font-size: 14px;
color: #999999;
background-color: #fff;
border: 2px solid #999999;
font-weight: 600;
}
.active-num {
color: #fff;
background-color: #1d70f5;
border: 2px solid #1d70f5;
}
.success-num {
color: #fff;
background-color: #00b42a;
border: 2px solid #00b42a;
}
.success-icon-num {
color: #00b42a;
font-size: 24px;
margin: 0 10px;
}
.text {
font-family: PingFang SC, PingFang SC;
font-size: 14px;
font-weight: 500;
color: #999999;
}
.active-text {
font-weight: 600;
color: #222222;
}
.success-text {
font-weight: 600;
color: #00b42a;
}
.line {
width: 108px;
height: 1px;
background-color: #cccccc;
margin-left: 10px;
}
.active-line {
background-color: #00b42a;
}
}
</style>
参考文档