作为一个前端初学者,公司项目中前端需要一个带分步式的进度条,查查Element-ui和Ant design Vue只有进度条和步骤条组件,缺乏一种分段式进度条。所以决定自己手写一个组件。结合自己项目的需求。
该分段式进度条需要根据当前时间来判断处于哪个阶段的多少进度中,传入的时间节点数据如下
stepsdateTime: [
{ nodestime: "2021-05-01 09:18:12", timePress: 0,nodename:"结点1" },
{ nodestime: "2021-05-08 09:18:12", timePress: 0,nodename:"节点2" },
{ nodestime: "2021-07-10 09:18:12", timePress: 0,nodename:"节点3" },
{ nodestime: "2021-07-18 09:18:12", timePress: 50,nodename:"节点4" },
{ nodestime: "2021-08-21 09:18:12", timePress: 50,nodename:"节点5" },
]
nodestime时间是传入的字符串,timepress是进度条的大小(最大为100),后面要将字符串时间转换为时间格式做时间大小判断,计算出timepress的值。
详细的代码
<template>
<div>
<div class="aa" style="display: flex; height: 125px; padding: 0 20px 20px 20px" >
<div v-for="(item,index) in activitySteps.slice(0, activitySteps.length - 1)" :key="index" style="width: 30%"
>
<div class="x" :style="{ width: pressheight + 'px', height: pressheight + 'px' }" >
<div class="timeDesc" style="">
<div style="height: 20px">
{{ item.nodestime.substring(0, 10) }}
</div>
<div style="height: 20px">{{ item.nodename }}</div>
</div>
</div>
<div class="pressPointA" :style="{ width: '100%', height: pressheight - 4 + 'px', backgroundColor: pressAcolor, }" >
<div :class="[item.timePress < 100 ? 'pointCss' : '']" :style="{ width: item.timePress + '%', height: '100%', backgroundColor: pressBcolor, }" ></div>
</div>
</div>
<div style="width: 10%">
<div class="x" :style="{ width: pressheight + 'px', height: pressheight + 'px' }" >
<div class="timeDesc" style="">
<div style="height: 20px">
{{ this.lastactivitySteps.nodestime }}
</div>
<div style="height: 20px">
{{ this.lastactivitySteps.nodename }}
</div>
</div>
</div>
</div>
</div>
<div>
<!-- <el-input v-show="isInputShow"><a-icon type="file-search" /></el-input> -->
</div>
</div>
</template>
<style>
.x {
border: 1px solid #21baa5;
border-radius: 60px;
position: absolute;
z-index: 1;
background-color: white;
/* margin-right: -16px; */
margin-left: -8px;
margin-top: -2px;
}
.timeDesc {
position: relative;
height: 100px;
width: 200px;
padding-top: 20px;
}
.pointCss {
border-radius: 0px 20px 20px 0;
}
</style>
<script>
import { format } from "date-fns";
export default {
name: "ActivityPress",
data() {
return {
//进度条大小
pressheight: 20,
//进度条背景颜色
pressAcolor: "gray",
//进度条颜色
pressBcolor: "#21baa5",
stepsdateTime: [
{ nodestime: "2021-05-01 09:18:12", timePress: 0, nodename: "结点1" },
{ nodestime: "2021-05-08 09:18:12", timePress: 0, nodename: "节点2" },
{ nodestime: "2021-07-10 09:18:12", timePress: 0, nodename: "节点3" },
{ nodestime: "2021-07-18 09:18:12", timePress: 50, nodename: "节点4" },
{ nodestime: "2021-08-21 09:18:12", timePress: 50, nodename: "节点5" },
],
lastactivitySteps: {},
timepress: [],
activitySteps: [],
active: 0,
};
},
watch: {
stepsData: {
handler() {
// this.timestoneCompute(this.stepsData)
this.timestoneCompute(this.stepsdateTime);
},
},
},
created() {
this.timestoneCompute(this.stepsdateTime);
},
methods: {
timestoneCompute(stepdata) {
this.activitySteps = stepdata;
this.lastactivitySteps = stepdata[stepdata.length - 1];
this.compareTime();
this.lastactivitySteps.nodestime = stepdata[
stepdata.length - 1
].nodestime.substring(0, 10);
},
//
compareTime() {
const curTime = format(new Date(), "yyyy-MM-dd HH:MM:SS");
const datatimearray = this.activitySteps;
// let a = this.compareTimestop(curTime, this.activitySteps[0].nodestime);
if (this.compareTimestop(curTime, this.activitySteps[0].nodestime)) {
for (const i in datatimearray) {
datatimearray[i].timePress = 0;
}
this.activitySteps = datatimearray;
} else if (
!this.compareTimestop(
curTime,
this.activitySteps[this.activitySteps.length - 1].nodestime
)
) {
for (const i in datatimearray) {
datatimearray[i].timePress = 100;
}
this.activitySteps = datatimearray;
} else {
// 当前时间的位置标志(比当前时间大的节点序号)
let timestopmark = 0;
for (const idex in datatimearray) {
// let a = this.compareTimestop(curTime, datatimearray[idex].nodestime);
if (this.compareTimestop(curTime, datatimearray[idex].nodestime)) {
timestopmark = idex;
break;
}
}
for (const index in datatimearray) {
// let a = this.compareTimestop(curTime, datatimearray[idex].nodestime);
if (index < timestopmark) {
if (timestopmark - index > 1) {
datatimearray[index].timePress = 100;
} else {
// 计算当前时间节点所占的比率 按小时做占比
const allTimeOne = this.getDifferDate(
this.getDate(datatimearray[index].nodestime),
this.getDate(datatimearray[timestopmark].nodestime),
2
);
const allTimeTwo = this.getDifferDate(
this.getDate(datatimearray[index].nodestime),
this.getDate(curTime),
2
);
const PoingTimePress = Math.floor(
(allTimeTwo / allTimeOne) * 100
);
datatimearray[index].timePress = PoingTimePress;
}
} else {
datatimearray[index].timePress = 0;
}
}
this.activitySteps = datatimearray;
}
},
next() {
if (this.active++ > 2) this.active = 0;
},
// 字符串转时间
getDate(strDate) {
var st = strDate;
var a = st.split(" ");
var b = a[0].split("-");
var c = a[1].split(":");
var date = new Date(b[0], b[1], b[2], c[0], c[1], c[2]);
return date;
},
// 字符串时间大小比较
compareTimestop(aTime, bTime) {
if (aTime.length > 0 && bTime.length > 0) {
var aTimeTemp = aTime.split(" ");
var bTimeTemp = bTime.split(" ");
var arrAdate = aTimeTemp[0].split("-");
var arrBdate = bTimeTemp[0].split("-");
var arraTime = aTimeTemp[1].split(":");
var arrbTime = bTimeTemp[1].split(":");
var allAdate = new Date(
arrAdate[0],
arrAdate[1],
arrAdate[2],
arraTime[0],
arraTime[1],
arraTime[2]
);
var allBdate = new Date(
arrBdate[0],
arrBdate[1],
arrBdate[2],
arrbTime[0],
arrbTime[1],
arrbTime[2]
);
if (allAdate.getTime() >= allBdate.getTime()) {
return false;
} else {
return true;
}
} else {
return false;
}
},
// 两个时间之间相差多少(天,时,分,秒)
getDifferDate(firstDate, secondDate, differ) {
// 1)将两个日期字符串转化为日期对象
// var startDate = new Date(firstDate);
// var endDate = new Date(secondDate);
// 2)计算两个日期相差的毫秒数
var msecNum = secondDate.getTime() - firstDate.getTime();
// 3)计算两个日期相差的天数
var dayNum = Math.floor(msecNum / this.getDifferScale(differ));
return dayNum;
},
// 获取与毫秒数的转化比例(相差天数:1,相差小时数:2,相差分钟数:3,相差秒数:4)
getDifferScale(value) {
var format;
// 获取转化比(天数跟毫秒数的比例)
if (value == 1) {
format = parseFloat(24 * 60 * 60 * 1000);
}
// 获取转化比(小时数跟毫秒数的比例)
else if (value == 2) {
format = parseFloat(60 * 60 * 1000);
}
// 获取转化比(分钟数跟毫秒数的比例)
else if (value == 3) {
format = parseFloat(60 * 1000);
}
// 获取转化比(秒数跟毫秒数的比例)
else if (value == 4) {
format = parseFloat(1000);
}
return format;
},
},
};
</script>
我的项目中是根据时间判断进度,有需要的小伙伴可以在此基础上修改为其他的进度条,传入合适的timepress值即可.