欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 汽车 > 时评 > 自定义分段式进度条

自定义分段式进度条

2024/10/26 5:19:53 来源:https://blog.csdn.net/qq_34465338/article/details/142827040  浏览:    关键词:自定义分段式进度条

背景

项目中需要一个进度条来展示处理的进度,要求如下:
1、需要进行分段,用来展示正常和异常状态;
2、异常状态需要提示信息

框架

vue3 + element-plus + TS

构思

一、进度条

在 div 中的 background 使用渐变属性 linear-gradient 来展示整个进度条的整体进度

二、异常状态

在进度条的 div 中添加新的 div 来展示异常进度,颜色可以自定义;最关键的是需要使用 margin-left: 属性来控制异常状态的进度

三、提示信息

这里使用了 element-plus 中的 popover 组件来实现

四、进度光标

实现方式跟异常状态一样,只是需要不断的进行删除和添加

代码

<template><div class="step-total" :style="{ background: getProgress() }"><el-popover v-for="block in abnormalBlock" trigger="hover" popper-class="popover-red" placement="bottom-start"><template #reference><div :style = "`width: ${block.width}px;height: ${block.height}px;background-color: ${block.color};margin-left: ${block.marginLeft}px;position: absolute;border-radius: ${block.borderRadius}px;`"/></template><div style="height: 100px"><div><span style="font-size: 20px; color: #a4a4a4; align-items: center">test</span><span style="font-size: 20px; float: right; align-items: center; color: #ffffff">{{block.id}}</span></div><hr style="border: none; border-top: 1px solid rgba(255, 255, 255, 0.1)" /><div><span style="font-size: 20px; color: #a4a4a4; align-items: center">test</span><span style="font-size: 20px; float: right; align-items: center; color: #ffffff">30%</span></div><hr style="border: none; border-top: 1px solid rgba(255, 255, 255, 0.1)" /><div><span style="font-size: 20px; color: #a4a4a4; align-items: center">test</span><span style="font-size: 20px; float: right; align-items: center; color: #ffffff">40%</span></div></div></el-popover></div><div> 步数:{{currentPercent/stepPercent}}/百分比:{{ currentPercent }}% </div><div><el-button @click="addNormalByPercent"> 添加正常(百分比)</el-button><el-button @click="addAbnormalByPercent"> 添加异常(百分比)</el-button></div><div><el-button @click="addNormalByStep"> 添加正常(步数)</el-button><el-button @click="addAbnormalByStep"> 添加异常(步数)</el-button></div><div><el-button @click="addPoint"> 添加光标 </el-button><el-button @click="delPoint"> 删除光标 </el-button></div>
</template>
<script setup lang="ts">
import { ref } from "vue";//进度条总长度
const progressWidth = 1200;
//每个百分比的宽度
const percentWidth = progressWidth / 100;
//总共的 step 数
const totalStep = 80;
//当前步数
const currentStep = ref(0)
//当前 step 百分比
const currentPercent = ref(0)
//每个 step 的百分比
const stepPercent = 100 / totalStep;
//每个 step 的宽度
const stepWidth = progressWidth / totalStep;
//异常模块
const abnormalBlock = ref([]);const getProgress = () => {//分段式进度条样式return `linear-gradient(to right, #528135 0%, #528135 ${ currentPercent.value }%,#ddd ${ currentPercent.value }%, #ddd 100%)`
}//百分比添加
const addNormalByPercent = () => {if(currentPercent.value == 100){return}delPoint()currentPercent.value ++;addPoint()
}//异常百分比添加
const addAbnormalByPercent = () => {if(currentPercent.value == 100){return}delPoint()abnormalBlock.value.push({id: currentPercent.value,width: percentWidth, //百分比的宽度是(总长度/100)height: 10,color: "red",marginLeft: currentPercent.value * percentWidth,borderRadius: 0})currentPercent.value ++;addPoint()
}//步数添加
const addNormalByStep = () => {if(currentPercent.value == 100){return}delPoint()currentStep.value ++;//当前 step 的百分比,当前步数*每步的百分比currentPercent.value = currentStep.value * stepPercent;addPoint()
}//异常步数添加
const addAbnormalByStep = () => {if(currentPercent.value == 100){return}delPoint()abnormalBlock.value.push({id: currentPercent.value,width: stepWidth,   //步数的宽度是每一步的宽度height: 10,color: "red",marginLeft: currentStep.value * stepWidth,borderRadius: 0})currentStep.value ++;//当前 step 的百分比,当前步数*每步的百分比currentPercent.value = currentStep.value * stepPercent;addPoint()
}//添加光标
const addPoint = () => {if(currentPercent.value == 100 || currentPercent.value == 0){return}abnormalBlock.value.push({id: "锚点",width: 3,   //步数的宽度是每一步的宽度height: 14,color: "black",marginLeft: currentPercent.value * percentWidth,borderRadius: 2})
}//移除光标
const delPoint = () => {const lastBlock = abnormalBlock.value[abnormalBlock.value.length - 1];if(lastBlock && lastBlock.id === "锚点"){abnormalBlock.value.pop();}
}</script>
<style lang="css">
.progress-div {display: flex;align-items: center;width: 100%;justify-content: space-between;
}
.step-total {width: 1200px;border-radius: 10px;height: 10px;align-items: center;display: flex;
}
.el-popover.popover-red {width: 224px !important;box-sizing: border-box;border-radius: 12px;border: 1px solid;border-bottom: 0;border-image: linear-gradient(to right, rgba(255, 255, 255, 0), rgba(236, 74, 41, 0.8), rgba(255, 255, 255, 0)) 1;background: linear-gradient(180deg,rgba(255, 161, 161, 0.99) -43.868%,rgba(161, 207, 255, 0.31) -27.981%,rgba(161, 207, 255, 0.2) -8.684%,rgba(162, 208, 255, 0.03) 25.187%,rgba(162, 208, 255, 0) 143.869%),rgba(18, 18, 18, 0.6);backdrop-filter: blur(2px);
}
.popover-red .el-popper__arrow {display: none;
}
</style>

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com