业务需求要求展示一个动态进度条,不同于第三方插件的进度条,这个ui设计的是断点式进度条,效果当然是美观大方,但是因为没有现成的第三方插件可以实现,这当然难不倒一个成熟的前端开发工程师。
根据ui设计可以看到进度条是由一定数目的小矩形拼成,并且占比情况下的矩形是一个比较亮的颜色,没有占比的颜色比较暗,这个感觉可以用动态背景色来实现,现在要考虑的是那些矩形的颜色是亮色,哪些是暗色,不难发现这就是个数学问题,当索引值小于某个值的时候之间展示活跃色,接下来直接代码实现吧
<template>
<div class="progress-wrapper">
<div class="total" :style="gridStyle">
<div
class="item"
v-for="i in splitNumber"
:key="i"
:style="{
background: i <= currentIndex ? activeColor : inactiveColor
}"
></div>
</div>
</div>
</template>
<script lang="ts" setup>
import { computed } from 'vue'
const props = defineProps({
// 当前数值(不是百分比)
current: {
type: Number,
default: 50
},
// 进度条总数
total: {
type: Number,
default: 100
},
// 分割的小矩形数量
splitNumber: {
type: Number,
default: 40
},
// 占比颜色
activeColor: {
type: String,
default: '#00fff5'
},
// 未占比颜色
inactiveColor: {
type: String,
default: '#09545f'
},
// 小矩形间的间距
gap: {
type: Number,
default: 4
}
})
const currentIndex = computed(() => {
return Math.floor((props.current / props.total) * props.splitNumber)
})
// 使用CSS变量避免强制重排
const gridStyle = computed(() => ({
'--columns': props.splitNumber,
'--gap': `${props.gap}px`
}))
</script>
<style scoped lang="scss">
.progress-wrapper {
width: 100%;
background: transparent;
height: 10px;
contain: layout paint;
.total {
display: grid;
width: 100%;
height: 100%;
background: transparent;
grid-auto-flow: column;
grid-template-columns: repeat(var(--columns), minmax(0, 1fr));
gap: var(--gap);
.item {
min-width: 0;
min-height: 0;
width: 100%;
height: 100%;
box-sizing: border-box;
transition: background-color 0.3s ease; /* 添加过渡效果 */
}
}
}
</style>
代码实现非常简单,比较有意思的是思考这一实现的过程,现在贴上效果图吧
如果你也觉得不错的话 留个脚印点个赞+关注吧