分段式进度条

因为业务需要自己写了个分段式进度条的组件Typescript + vue + vexipUi

 整体思路就是先有个外容器,包裹着三个模块,分别为起始日期、进度条和截止日期。

进度条模块:

更据宽度来计算格子的数量,格子的宽度固定,需要监听进度条模块容器的宽度

进度百分比 = (现在时间 - 起始时间)/ (结束时间 - 起始时间)

染色格子的数量 = 总格子数量 *(现在时间 - 起始时间)/ (结束时间 - 起始时间)

算出染色格子数量后渲染颜色,在最后一个染色格子上包裹一个tootip

 

 

<template>
  <div :class="prefix">
    <span :class="`${prefix}__left`">2022-02-01</span>
    <div ref="tickWrapper" :class="`${prefix}__container`">
      <template v-for="tick in totaltick" :key="tick">
        <VTooltip v-if="tick === index">
          <template #trigger>
            <div :class="`${prefix}__tick-container`">
              <div :class="[`${prefix}__tick`, tick === index && `${prefix}__tick--active`]"></div>
            </div>
          </template>
         <span>要提示的内容</span>
        </VTooltip>
        <div v-else :class="`${prefix}__tick-container`">
          <div :class="[`${prefix}__tick`, tick < index && `${prefix}__tick--active`]"></div>
        </div>
      </template>
    </div>
    <span :class="`${prefix}__right`">2024-06-31</span>
  </div>
</template>

<script setup lang="ts">
const prefix = 'progress'
let resizeObserver: ResizeObserver | null = null
const tickWrapper = ref<HTMLElement>()
const totaltick = ref<number>(0)
const index = ref(0)

const startDate = new Date('2022-02-01')
const endDate = new Date('2024-06-31')
const nowDate = new Date()
const totalDifference = 1 + (endDate.getTime() - startDate.getTime()) / (1000 * 3600 * 24)
const timeDifference = 1 + (nowDate.getTime() - startDate.getTime()) / (1000 * 3600 * 24)
const percentage = timeDifference / totalDifference

let width = 0

onMounted(() => {
  if (tickWrapper.value) {
    resizeObserver = new ResizeObserver(calculateContentHeight)
    resizeObserver.observe(tickWrapper.value)
  }
})

function calculateContentHeight() {
  width = tickWrapper.value?.offsetWidth ?? 0
  totaltick.value = Math.floor(width / 12)
  index.value = Math.floor(percentage * totaltick.value)
}
</script>

<style lang="scss" scoped>
.progress {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 40px;
  padding: 4px;
  background: #0e233c;
  border: 1px solid #1c5c82;
  opacity: 82%;

  &__right {
    position: absolute;
    right: 0;
    width: 13%;
    padding: 12px;
    text-align: center;
  }

  &__left {
    position: absolute;
    left: 0;
    width: 13%;
    padding: 12px;
    text-align: center;
  }

  &__container {
    position: absolute;
    display: flex;
    width: 73%;
    height: 30%;
  }

  &__tick-container {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    height: 100%;
    cursor: pointer;
  }

  &__tick {
    width: 6px;
    height: 100%;
    margin-right: 6px;
    background: #26384b;
    opacity: 82%;

    &--active {
      background: #38baff;
    }
  }
}
</style>

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值