封装一个子组件
<template>
<div class="my-step" v-if="stepData && stepData.length > 0">
<div class="w100 f-arrayX" :class="i % 2 !== 0 ? 'f-levelR' : 'f-levelL'" v-for="(site, i) in stepData" :key="i">
<div class="f-arrayX" :style="{ marginBottom: lineHeight - 30 + 'px' }" v-for="(item, j) in site" :key="j">
<div style="position: relative">
<div class="step-icon f-center">
<div class="top-title">
<slot :data="item" name="top"></slot>
</div>
<div class="center w100 h100">
<slot :data="item" name="center"> </slot>
</div>
<div class="bottom-title">
<slot :data="item" name="bottom"></slot>
</div>
</div>
<!-- 横向线条 -->
<div
v-if="j + 1 !== site.length"
:style="{ width: lineWidth + 50 + 'px' }"
:class="[
i % 2 == 1 ? 'myarrow-row-left' : 'myarrow-row-right',
i * rowCount + (i % 2 == 0 ? j + 1 : site.length - j - 1) < activeIndex && item.light === true ? 'activeColor' : 'grayColor'
]"
></div>
<!-- 首尾折线 -->
<div
v-if="((j == 0 && i % 2 == 1) || (j + 1 == site.length && i % 2 == 0)) && i + 1 != stepData.length"
:style="{ height: lineHeight + 'px' }"
:class="[
i % 2 == 1 ? 'myarrow-left' : 'myarrow-right',
i * rowCount + (i % 2 == 0 ? rowCount : rowCount - j) < activeIndex && item.light === true ? 'activeBorderColor' : 'activeGrayColor'
]"
></div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
name: '',
components: {},
props: {
lineWidth: {
default: 250
},
lineHeight: {
default: 250
},
data: {
type: Array,
default: () => []
},
rowCount: {
type: Number,
default: 0
},
activeIndex: {
type: Number,
default: 0
}
},
data() {
return {};
},
computed: {
stepData() {
if (!this.data) return [];
let arr = [];
console.log(this.data);
let count = 0;
for (let i = 0; i < this.data.length; i += this.rowCount) {
let arrItem = this.data.slice(i, i + this.rowCount);
arr.push(count % 2 == 0 ? arrItem : arrItem.reverse());
count++;
}
console.log(arr);
return arr;
}
},
created() {},
mounted() {},
methods: {},
watch: {}
};
</script>
<style lang='scss' scoped>
.my-step {
width: fit-content;
max-width: 100%;
height: 100%;
padding: 100px;
background-color: #fff;
.step-icon {
position: relative;
width: 30px;
height: 30px;
background-color: #fff;
z-index: 10;
.top-title {
position: absolute;
bottom: 30px;
width: 100px;
text-align: center;
font-weight: 600;
font-size: 17px;
}
.bottom-title {
position: absolute;
top: 40px;
width: 200px;
}
}
.myarrow-right::before {
position: absolute;
bottom: -6px;
content: '';
width: 10px;
height: 10px;
clip-path: polygon(0 50%, 100% 100%, 100% 0);
background-color: #000;
}
.myarrow-left::before {
position: absolute;
bottom: -6px;
right: -2px;
content: '';
width: 10px;
height: 10px;
clip-path: polygon(0 0, 0% 100%, 100% 50%);
background-color: #000;
}
.myarrow-right {
position: absolute;
width: 180px;
top: 16px;
left: 26.5px;
border-radius: 0 5px 5px 0;
border: 2px solid #000;
border-left-color: rgba(0, 0, 0, 0) !important;
}
.myarrow-left {
position: absolute;
width: 157px;
left: -160px;
top: 15px;
border-radius: 5px 0px 0px 5px;
border: 2px solid #000;
border-right-color: rgba(0, 0, 0, 0) !important;
}
.myarrow-row-right,
.myarrow-row-left {
height: 2px;
// background-color: #000;
background-color: rgba(0, 0, 0, 0.3);
transform: translateY(-15px);
}
.myarrow-row-right::before {
position: absolute;
bottom: -4px;
content: '';
right: 0;
width: 10px;
height: 10px;
clip-path: polygon(0 0, 0% 100%, 100% 50%);
background-color: currentColor;
}
.myarrow-row-left::before {
position: absolute;
bottom: -4px;
left: 30px;
content: '';
width: 10px;
height: 10px;
clip-path: polygon(0 50%, 100% 100%, 100% 0);
background-color: currentColor;
}
.activeColor {
background-color: #5cb8b2;
}
.grayColor {
background-color: rgba(0, 0, 0, 0.6);
}
.activeBorderColor {
border-color: #5cb8b2;
}
.activeGrayColor {
border-color: rgba(0, 0, 0, 0.6);
}
.activeColor::before {
color: #5cb8b2 !important;
}
.activeBorderColor::before {
background-color: #5cb8b2 !important;
}
}
.mb100 {
margin-bottom: 85px;
}
.ml100 {
margin-left: 100px;
}
</style>
父组件
<template>
<div class="w100 h100">
<el-drawer title="账单历程" :visible.sync="processVisibel" direction="rtl" :append-to-body="true" size="87%" :before-close="processHandleClose" :close-on-click-modal="false">
<mystep :data="stepData" :rowCount="4" :activeIndex="stepDataNurm">
<div slot="top" slot-scope="scope">
{{ scope.data.title }}
</div>
<div slot="center" slot-scope="scope">
<i v-if="scope.data.light === true" class="el-icon-circle-check"></i>
<i v-else class="el-icon-edit"></i>
</div>
<div slot="bottom" slot-scope="scope">
<div class="openCss" v-if="scope.data.light === true">
{{ scope.data.name }}
</div>
<div v-else class="elseOpenCss">
{{ scope.data.name }}
</div>
<div class="operationCss">
<div v-if="scope.data.creatorName">操作人: {{ scope.data.creatorName }}</div>
<div v-if="scope.data.adjustType">
<div v-if="scope.data.adjustType === 1">调整类型:账单修改</div>
<div v-if="scope.data.adjustType === 2">调整类型:账单挪账</div>
<div v-if="scope.data.adjustType === 3">调整类型:账单调差</div>
<div v-if="scope.data.adjustType === 4">调整类型:一次性调整</div>
</div>
</div>
</div>
</mystep>
</el-drawer>
</div>
</template>
<script>
import tableMixins from '@/mixins/tableMixins';
import mystep from '../components/mystep.vue';
import axios from '@/router/axios.js';
export default {
title: '账单历程',
components: { mystep },
mixins: [tableMixins],
props: {
processVisibel: {
type: Boolean
},
billNodeList: {
type: Array,
default: () => {
return [];
}
}
},
data() {
return {
stepData: [],
billNodeNew: [],
bill_node: [],
adjust_type: [],
stepDataNurm: 0
};
},
created() {
this.getRedisDict(['bill_node']);
// this.getRedisDict2(['adjust_type']);
},
watch: {
billNodeList: {
deep: true,
handler: function () {
this.stepData = [];
this.billNodeNew = this.billNodeList;
console.log(this.billNodeNew, this.bill_node);
this.billNodeNew.forEach(item => {
this.bill_node.forEach(ele => {
if (item.billNode === ele.value) {
item.billName = ele.name;
this.stepData.push({ title: item.createTime, name: ele.name, light: item.light, creatorName: item.creatorName, adjustType: item.adjustType });
}
});
});
this.stepDataNurm = this.stepData.length;
console.log(this.stepDataNurm, this.stepData);
}
}
},
methods: {
getRedisDict(arr = []) {
//查词典
arr.forEach(item => {
axios({
url: '/commonController/getRedisDict',
method: 'post',
params: {
key: item
}
}).then(res => {
this.bill_node = res.data;
});
});
},
// getRedisDict2(arr = []) {
// //查词典
// arr.forEach(item => {
// axios({
// url: '/commonController/getRedisDict',
// method: 'post',
// params: {
// key: item
// }
// }).then(res => {
// console.log(res);
// this.adjust_type = res.data;
// });
// });
// },
processHandleClose(done) {
done();
this.$emit('update:processVisibel', false);
}
}
};
</script>
<style lang="scss" scoped>
/deep/.iconCss {
border: none !important;
padding: 0px 0px 0px 2px;
}
/deep/.el-drawer__header {
color: #ffffff;
margin-bottom: 32px;
background-color: #5cb8b2;
padding: 10px;
height: 10px;
display: flex !important;
font-size: 13px;
}
/deep/.el-drawer__close-btn {
font-size: 11px !important;
}
/deep/.el-icon-edit {
font-weight: 600 !important;
font-size: 25px !important;
color: rgba(0, 0, 0, 0.3);
}
/deep/.el-icon-circle-check {
font-weight: 600 !important;
font-size: 25px !important;
color: #5cb8b2;
}
// -----------------------
/deep/.my-step {
position: relative;
/* width: 90%;
height: 100%;
padding-left: 100px; */
padding: 100px 0px 100px 160px !important;
background-color: #fff;
.step-icon {
position: relative;
width: 30px;
height: 30px;
background-color: #fff;
z-index: 10;
.top-title {
position: absolute;
bottom: 30px;
font-size: 13px !important;
}
.bottom-title {
position: absolute;
top: 30px;
width: 118px;
.operationCss {
text-align: center;
color: rgba(0, 0, 0, 0.3);
font-weight: 600;
font-size: 12px;
}
.openCss {
text-align: center;
font-size: 15px;
font-weight: 600;
}
.elseOpenCss {
text-align: center;
font-size: 15px;
font-weight: 600;
color: rgba(0, 0, 0, 0.3);
}
}
}
.myarrow-right::before {
position: absolute;
bottom: -5px;
// right: -11px;
// transform: translate(-5px,105px);
content: '';
width: 10px;
height: 10px;
clip-path: polygon(0 50%, 100% 100%, 100% 0);
background-color: #000;
}
.myarrow-left::before {
position: absolute;
bottom: -5px;
right: 0px;
// transform: translate(-5px,105px);
content: '';
width: 10px;
height: 10px;
clip-path: polygon(0 0, 0% 100%, 100% 50%);
background-color: #000;
}
.myarrow-right {
position: absolute;
width: 100px;
// height: 115px;
top: 15px;
left: 30px;
border-radius: 0 5px 5px 0;
border: 1px solid #000;
border-left-color: rgba(0, 0, 0, 0);
}
.myarrow-left {
position: absolute;
width: 100px;
// height: 115px;
left: -100px;
top: 15px;
border-radius: 5px 0px 0px 5px;
border: 1px solid #000;
border-right-color: rgba(0, 0, 0, 0);
}
.myarrow-row-right,
.myarrow-row-left {
height: 1px;
background-color: #000;
transform: translateY(-15px);
width: 220px !important;
}
.myarrow-row-right::before {
position: absolute;
bottom: -5px;
content: '';
right: 0;
width: 10px;
height: 10px;
clip-path: polygon(0 0, 0% 100%, 100% 50%);
background-color: currentColor;
}
.myarrow-row-left::before {
position: absolute;
bottom: -5px;
left: 30px;
content: '';
width: 10px;
height: 10px;
clip-path: polygon(0 50%, 100% 100%, 100% 0);
background-color: #000;
}
.activeColor {
background-color: #5cb8b2;
}
.grayColor {
background-color: rgba(0, 0, 0, 0.6);
}
.activeBorderColor {
border-color: #5cb8b2;
}
.activeGrayColor {
border-color: rgba(0, 0, 0, 0.6);
}
.activeColor::before {
color: #5cb8b2 !important;
}
.activeBorderColor::before {
background-color: #5cb8b2 !important;
}
}
.mb100 {
margin-bottom: 85px;
}
.ml100 {
margin-left: 100px;
}
.f-center {
display: flex;
justify-content: center;
align-items: center;
}
.f-base {
display: flex;
flex-flow: row wrap;
align-content: flex-start;
}
.f-baseX {
display: flex !important;
align-items: center;
}
// .f-space {
// flex-grow: 1;
// }
</style>