前端简易实现计划(分阶段)多色进度条

需求

已知数据

不同阶段的完成时间点(这里以三个阶段举例,依次为备货阶段,装配阶段,测试阶段)
计划的开始结束时间

要求实现功能

将当前日期处于哪个阶段用进度条展示出来
不同的阶段用不同的背景色显示
如果当前日期小于阶段计划完成时间点,需要将未完成时间点标记出来

最终效果图在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

核心思路

  • 天数计算
  • linear-gradient的应用:实现不同计划阶段不同颜色,及阶段时间点标记

代码实现

下面代码以vue为例

<template>
 	<div class="progress-div">
        <div class="step-total" :style="{ background: getRule(record, 'style') }"></div>
        <span>{{ getRule(record, 'percent') }} </span>
        <span> {{ getRule(record, 'text') }}</span>
	</div>
</template>
<script>
 data(){
	record: {
	  //这里的时间顺序一定是 计划开始时间<=备货截止日期<=装配截止日期<=测试截止日期<=计划结束时间
	  beginTime: '2024-04-01',
      endTime: '2024-05-14',
      //备货截止日期
      stockEndTime: '2024-04-08',
      //装配截止日期
      assembleEndTime: '2024-04-27',
      //测试截止日期
      testEndTime: '2024-05-14'
	}
},
 methods:{
    //工具方法用于计算两个日期天数差
	 getDaysBetween(date1, date2) {
	      const startDate = Date.parse(date1)
	      const endDate = Date.parse(date2)
	      if (startDate > endDate) {
	        return 0
	      }
	      if (startDate == endDate) {
	        return 1
	      }
	      const days = parseInt((endDate - startDate) / (24 * 60 * 60 * 1000))
	      return days
	    },
	    //通过style动态绑定更改背景色,这里还获取了百分比和当前状态文字,也可以不用switch直接返回一个对象
	    getRule(record, label) {
	      let bg = ''
	      let text = '未开始'
	      //总天数
	      const days = this.getDaysBetween(record.beginTime, record.endTime)
	      //备货天数
	      const stockDays = this.getDaysBetween(record.beginTime, record.stockEndTime)
	      //备货占比
	      const stockRate = parseInt((stockDays / days) * 100)
	      //装配天数
	      const assembleDays = this.getDaysBetween(record.beginTime, record.assembleEndTime)
	      //装备占比
	      const assembleRate = parseInt((assembleDays / days) * 100)
	      //测试天数
	      const testDays = this.getDaysBetween(record.beginTime, record.testEndTime)
	      //测试占比
	      const testRate = parseInt((testDays / days) * 100)
	      //当前过去几天
	      const currentDays = this.getDaysBetween(record.beginTime, new Date().toISOString().slice(0, 10).replace(/-/g, '-'))
	      //当天占比
	      const currentRate = parseInt((currentDays / days) * 100)
	      //全部完成
	      if (currentDays >= testDays) {
	        text = '已完成'
	        bg = `linear-gradient(to right, #e1eed9 0%, #e1eed9 ${stockRate}%,#a8d08d ${stockRate}%,#a8d08d ${assembleRate}%,#528135 ${assembleRate}%, #528135 ${testRate}%,#ddd ${testRate}%,#ddd 100%)`
	      }
	      //测试中
	      if (currentDays < testDays && currentDays >= assembleDays) {
	        text = '测试中'
	        bg = `linear-gradient(to right, #e1eed9 0%, #e1eed9 ${stockRate}%,#a8d08d ${stockRate}%,#a8d08d ${assembleRate}%,#528135 ${assembleRate}%, #528135 ${currentRate}%,#ddd ${currentRate}%,#ddd ${
	          testRate - 0.5
	        }%,#528135 ${testRate - 0.5}%,#528135 ${testRate}%,#ddd ${currentRate}%,#ddd 100%)`
	      }
	      //装配中
	      if (currentDays < assembleDays && currentDays >= stockDays) {
	        text = '装配中'
	        bg = `linear-gradient(to right, #e1eed9 0%, #e1eed9 ${stockRate}%,#a8d08d ${stockRate}%,#a8d08d ${currentRate}%,#ddd ${currentRate}%,#ddd ${
	          assembleRate - 0.5
	        }%,#a8d08d ${assembleRate - 0.5}%,#a8d08d ${assembleRate}%,#ddd ${assembleRate}%,#ddd ${
	          testRate - 0.5
	        }%,#528135 ${testRate - 0.5}%,#528135 ${testRate}%,#ddd ${testRate}%,#ddd 100%)`
	      }
	      //备货中
	      if (currentDays < stockDays && currentDays > 0) {
	        text = '备货中'
	        bg = `linear-gradient(to right, #e1eed9 0%, #e1eed9 ${currentRate}%,#ddd ${currentRate}%,#ddd ${
	          stockRate - 0.5
	        }%,#e1eed9 ${stockRate - 0.5}%,#e1eed9 ${stockRate}%,#ddd ${stockRate}%,#ddd ${assembleRate - 0.5}%,#a8d08d ${
	          assembleRate - 0.5
	        }%,#a8d08d ${assembleRate}%,#ddd ${assembleRate}%,#ddd ${testRate - 0.5}%,#528135 ${
	          testRate - 0.5
	        }%,#528135 ${testRate}%,#ddd ${testRate}%,#ddd 100%)`
	      }
	      //未开始
	      if (currentDays == 0) {
	        bg = `linear-gradient(to right, #ddd 0%, #ddd ${stockRate - 0.5}%,#e1eed9 ${
	          stockRate - 0.5
	        }%,#e1eed9 ${stockRate}%,#ddd ${stockRate}%,#ddd ${assembleRate - 0.5}%,#a8d08d ${
	          assembleRate - 0.5
	        }%,#a8d08d ${assembleRate}%,#ddd ${assembleRate}%,#ddd ${testRate - 0.5}%,#528135 ${
	          testRate - 0.5
	        }%,#528135 ${testRate}%,#ddd ${testRate}%,#ddd 100%)`
	      }
	      switch (label) {
	        case 'style':
	          return bg
	        case 'text':
	          return text
	        case 'percent':
	          return parseInt((currentDays / days) * 100) + '%'
	      }
    }
<script>
<style lang="css">
	.progress-div {
	  display: flex;
	  align-items: center;
	  width: 100%;
	  justify-content: space-between;
	}
	.step-total {
	  width: 200px;
	  border-radius: 10px;
	  height: 10px;
	}
</style>
  • 7
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值