进度条组件,文字随进度条长度自定义文字位置颜色

最近接到一个数据统计的需求,要求里面的进度条文字随着进度条的长度往后移动,当进度条剩余灰色的长度小于显示的文字长度的时候,文字就要展示在进度条的内部,并且文字的颜色也要变成白色,找了一圈也没有合适的,就自己写了一个进度条组件,大家有差不多的可以根据自己的需求修改一下。

组件效果图:

 HTML部分:

<template>
  <div class="progress-bar">
    <div class="progress-wrapper" ref="bottomRef">
      <div
        class="progress-left"
        ref="lineRef"
        :style="{ width: title > 100 ? '100%' : title + '%' }"
      >
        <div
          ref="textRef"
          class="text"
          :style="{
            right: textWidth,
            color: distanceIsExceeded ? color : '#000000',
          }"
        >
          {{ text }}
        </div>
      </div>
    </div>
  </div>
</template>

 script部分:

<script setup>
import { defineProps, nextTick, onMounted, ref, toRefs, watch } from "vue";
const props = defineProps({
  progress: {
    type: String,
    default: "0%",
  },
  text: {
    type: String,
    default: "",
  },
});
let { progress, text } = toRefs(props);
const bottomRef = ref();//灰色部分ref
const lineRef = ref();//进度条ref
const textRef = ref();//文本ref
const textWidth = ref("");//文本的宽度
const distance = ref();//剩余灰色的长度
const color = ref("#ffffff");
const distanceIsExceeded = ref(false);//文字是否超出
const title = ref();//进一步判断防止超过100%的情况
onMounted(() => {
  if (progress.value) {
    calculateDistance();
    //监听屏幕变化,重新计算
    window.addEventListener("resize", function () {
      calculateDistance();
    });
  }
});
//当数据props改变时触发,重新计算
watch(progress, (newValue, oldValue) => {
  if (newValue) {
    calculateDistance();
  }
});
/**
 * 计算进度条的进度以及文字的显示位置
 */
const calculateDistance = () => {
  if (progress.value) {
    title.value = progress.value;
    title.value = Number(title.value.split("%")[0]);
    nextTick(() => {//当数据更新完毕在进行计算
      distance.value = Number(
        bottomRef.value.offsetWidth - lineRef.value.offsetWidth
      );
      if (textRef.value.offsetWidth >= distance.value) {
        textWidth.value = "1px";
        distanceIsExceeded.value = true;
      } else {
        textWidth.value = "-" + textRef.value.offsetWidth + "px";
        distanceIsExceeded.value = false;
      }
    });

  }
};
</script>

 css部分:

<style scoped>
.progress-bar {
  display: flex;
  align-items: center;
  width: 100%;
}

.progress-wrapper {
  position: relative;
  flex-grow: 1;
  height: 20px;
  background-color: #eee;
  overflow: hidden;
  border-top-right-radius: 10px;
  border-bottom-right-radius: 10px;
}

.progress-left {
  position: absolute;
  top: 0;
  left: 0;
  height: 100%;
  width: 0px;
  text-align: right;
  background-color: #409eff;
  border-top-right-radius: 10px;
  border-bottom-right-radius: 10px;
  /*transition: width 0.3s;*/
}
.text {
  padding: 0 3px;
  font-size: 14px;
  position: absolute;
  top: 0;
  line-height: 20px;
  white-space: nowrap;
}
</style>

如何使用该组件:

import ProgressBar from "@/components/progress-bar/progress-bar";

<ProgressBar
:progress="item.rate + ''"//进度(字符串%)
:text="`${item.abnormalNumber}人/${item.rate}`"//显示的文字内容
>
</ProgressBar>

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值