加载进度条demo

<template>
  <div class="progress-box">
    <div class="container">
      <div class="loading-icon" ></div>
      <div class="loading-bar">
        <div class="progress" :style="{ width: process + '%'}"></div>
      </div>
      <div class="loading-text">{{ `${Math.floor(this.current*100)/100}M/${this.total}M` }}</div>
    </div>
  </div>
</template>

<script>
export default {
  data() { 
    return {
      total: 20,
      current: 0,
      timer: null
    }
  },
  methods: {
    progressing(period) {
      let _self = this;
      clearTimeout(this.timer);
      this.timer = setTimeout(function timeoutFun() {
        if (_self.current >= _self.total) {
          clearTimeout(_self.timer);
        } else {
          let random = Math.random() + 1;
          _self.current = random + _self.current > _self.total ? _self.total : random + _self.current;
          _self.updateProgress();
          let nextPeriod = Math.random() * 30 + 100;
          clearTimeout(_self.timer);
          _self.timer = setTimeout(timeoutFun, nextPeriod);
        }
      }, period);
    },
    updateProgress() {
      let percent = this.current / this.total;
      let container = document.getElementsByClassName('container')[0];
      let icon = document.getElementsByClassName('loading-icon')[0];
      let left = container.offsetWidth * percent - 20;
      if (left < 0) left = 0;
      icon.style.left = `${left}px`;
    }
  },
  computed: {
    process() {
      return this.current / this.total * 100;
    }
  },
  mounted() {
    window.onresize = this.updateProgress;
  },
  created() {
    this.progressing(100);
  }
 }
</script>

<style lang="sass" scoped>
  .progress-box
    min-width: 300px
    max-width: 900px
    padding: 0 50px
    margin: 100px auto
    .container
      position: relative
    .loading-icon
      position: absolute
      left: 0px
      top: -26px
      width: 20px
      height: 20px
      border-radius: 50%
      background-color: #000
      transition: .25s
    .loading-bar
      width: 100%
      height: 10px
      background-color: #d6e6f7
      border-radius: 20px
      .progress
        width: 0px
        height: 100%
        background-color: #007fff
        border-radius: 20px
        transition: .25s
    .loading-text
      margin-top: 6px
      text-align: right
      font-size: 14px
      color: #ccc
    
</style>

注意点:

(1)模拟数据加载的速度,涉及到了每次加载的间隔随机,在setTimeout中的callback使用声明函数(而不用匿名方法),用于方法内递归调用。

(2)宽度的百分比是参照其父元素,但是translateX(translateY)的百分比是参照其本身的宽高,因此这里采用left属性(以父级的宽度为基准)来动态设置icon的位置;

(3)由于icon自身也有宽度,因此移动的距离要减去自身的宽度,这里用js计算更为方便,但要考虑到加载过程中若浏览器窗口大小改变而导致icon错误的问题,因此要增加监听窗口变化的事件,重新计算icon的位置

(4)利用transition可使进度条位置的改变更为平滑

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值