美文网首页
一个移动端进度条

一个移动端进度条

作者: 喑宝儿 | 来源:发表于2021-08-25 14:29 被阅读0次

    简介

    利用js原生写的一个移动端进度条

    效果展示

    效果图
    灰心图标 红心图标

    代码实现

    <template>
      <div class="steps flex flex-wrap">
        <div class="step-item flex flex-col flex-items flex-jc" v-for="(item, index) in arr" :key="index">
          <!-- 可自由发挥的地方 -->
          <div class="flex flex-items flex-jc">{{item.rank}}</div>
          <!-- 可自由发挥的地方结束 -->
          <div class="step-word">{{item.num}}</div>
          <div class="step-line"></div>
          <div class="heart-icon flex flex-item flex-jc">
            <img width="15" :src="!item.done ? 'https://img-blog.csdnimg.cn/52f0ece61c264672bc87a8ac85e48a3f.png' : 'https://img-blog.csdnimg.cn/47a05243bb174f6b9415ed3a64c08a02.png'" alt="">
          </div>
          <div class="step-now flex flex-items flex-jc" style="display: none;">{{now}}</div>
        </div>
      </div>
    </template>
    
    <script>
    export default {
      name: 'Step',
      props: {
        arr: {
          type: Array,
          required: true
        },
        now: {
          type: Number
        }
      },
      data () {
        return {}
      },
      created () {},
      mounted () {
        var items = document.querySelectorAll('.step-line')
        var signs = document.querySelectorAll('.step-now')
        var index = 0
        if (this.now < this.arr[0].num) {
          items[0].style.width = this.now / this.arr[0].num * 50 + '%'
          index = 0
        } else if (this.now >= this.arr[this.arr.length - 1].num) {
          for (var i = 0; i < this.arr.length - 1; i++) {
            items[i].style.width = '100%'
            this.$set(this.arr[i], 'done', true)
          }
          items[this.arr.length - 1].style.width = '50%'
          this.$set(this.arr[this.arr.length - 1], 'done', true)
        } else {
          for (var j = 0; j < this.arr.length - 1; j++) {
            if (this.now > this.arr[j].num) {
              if (this.now - this.arr[j].num > (this.arr[j + 1].num - this.arr[j].num) / 2) {
                items[j].style.width = '100%'
                this.$set(this.arr[j], 'done', true)
                items[j + 1].style.width = (this.now - this.arr[j].num) / (this.arr[j + 1].num - this.arr[j].num) * 100 - 50 + '%'
                if (items[j + 1].style.width === '50%') {
                  this.$set(this.arr[j + 1], 'done', true)
                }
                index = j + 1
                continue
              }
              items[j].style.width = (this.now - this.arr[j].num) / (this.arr[j + 1].num - this.arr[j].num) * 100 + 50 + '%'
              index = j
              this.$set(this.arr[j], 'done', true)
              break
            }
          }
        }
        if (this.now < this.arr[this.arr.length - 1].num) {
          signs[index].style.display = 'block'
          signs[index].style.left = items[index].style.width
          signs[index].style.transform = 'translateX(-50%)'
        }
      },
      methods: {}
    }
    </script>
    
    <style lang="less" scoped>
    .flex {
      display: flex;
    }
    
    .flex-items {
      align-items: center;
    }
    
    .flex-jc {
      justify-content: center;
    }
    
    .flex-bet {
      justify-content: space-between;
    }
    
    .flex-aro {
      justify-content: space-around;
    }
    
    .flex-wrap {
      flex-wrap: wrap;
    }
    
    .flex-col {
      flex-direction: column;
    }
    
    .steps {
      width: 100%;
    
      .step-item {
        position: relative;
        width: 33%;
        margin: 10px 0;
        padding-bottom: 10px;
    
        .step-line {
          position: absolute;
          width: 0;
          height: 1px;
          background: #f00;
          left: 0;
          bottom: 0;
          z-index: 5;
        }
    
        .step-now {
          font-size: 8px;
          color: #fff;
          position: absolute;
          padding: 1px 4px;
          bottom: 0;
          height: 26px;
          line-height: 26px;
          z-index: 15;
          background: url(http://h5.dongjinyu.com/icon/20210825094601_6125a0d92163e.png);
          background-size: 100% 100%;
        }
    
        .heart-icon {
          position: absolute;
          width: 20px;
          bottom: -8px;
          background: #fff;
          z-index: 10;
        }
      }
    
      .step-item:not(:last-child):before {
        width: 100%;
        height: 1px;
        content: '';
        position: absolute;
        left: 0;
        bottom: 0;
        background: #E9E9E9;
      }
    
      .step-item:last-child:before {
        width: 50%;
        height: 1px;
        content: '';
        position: absolute;
        left: 0;
        bottom: 0;
        background: #E9E9E9;
      }
    }
    </style>
    

    使用方式

    1、引用使用
    <Step :arr="list" :now="now"></Step>
    
    2、传入参数样例
    list: [{
      num: 100,
      rank: '幼儿园'
    }, {
      num: 200,
      rank: '小学'
    }, {
      num: 400,
      rank: '初中'
    }, {
      num: 800,
      rank: '高中'
    }, {
      num: 1600,
      rank: '大学'
    }, {
      num: 3200,
      rank: '硕士'
    }, {
      num: 6400,
      rank: '博士'
    }, {
      num: 12800,
      rank: '博士后'
    }, {
      num: 25600,
      rank: '博士导师'
    }, {
      num: 51200,
      rank: '国宝'
    }],
    now: 730
    
    3、注意事项

    (1)每一项的rank内容部分可以自由发挥
    (2)如果传入的list数组中的数值键名不是num,需要在vue文件中的js中将所有num改为list数组中数值的键名,dom项的属性也自行修改

    相关文章

      网友评论

          本文标题:一个移动端进度条

          本文链接:https://www.haomeiwen.com/subject/vlosiltx.html