index.vue 4.13 KB
<template>
  <div class="slider">
    <div ref="slider" class="slider" :style="'width:'+width+'px;background:'+bgcolor">
      <div
        v-for="(item,index) in data"
        :key="index"
        class="sbox"
        :class="'s'+index"
        :index="index"
        :style="'width:'+((1*width-30)*parseInt(item.bl.replace('%',''))/100+30)+'px;background:'+item.color+';z-index:'+(8-index)"
      >
        <div class="round-bg" @mousedown="down($event)">
          <span class="bl">{{ item.bl }}</span>
          <div class="round" :style="'background:'+item.color" />
          <span class="jb">{{ item.name }}</span>
        </div>
      </div>
      <div class="perfect">
        <span class="bl">100%</span>
        <div class="icon_img"><img :src="require('@/assets/images/IMG_1789.png')" alt=""></div>
        <span class="jb">优秀</span>
      </div>
    </div>
  </div>
</template>
<script>
export default {
  name: 'Slider',
  props: {
    data: {
      type: Array,
      default: function() {
        return []
      }
    },
    // eslint-disable-next-line vue/require-default-prop
    width: [String, Number],
    bgcolor: {
      type: String,
      default: ''
    }

  },
  data() {
    return {
      startX: 0,
      sliderFlag: false,
      prevWidth: '',
      nextWidth: '',
      obj: {}
    }
  },
  methods: {
    down(event) {
      event.preventDefault()
      this.startX = event.clientX
      this.sliderFlag = true
      this.getEle(event.target) // 获取父级元素
      console.log(this.obj.getAttribute('index'))
      if (this.obj.getAttribute('index') === '0') {
        this.prevWidth = '30px'
        this.nextWidth = parseInt(this.obj.nextElementSibling.style.width.replace('px', '') - 30) + 'px'
      } else if (this.obj.getAttribute('index') === (this.data.length - 1 + '')) {
        this.prevWidth = parseInt(this.obj.previousElementSibling.style.width.replace('px', '')) + 30 + 'px'
        this.nextWidth = this.$refs.slider.offsetWidth + 'px'
      } else {
        this.prevWidth = parseInt(this.obj.previousElementSibling.style.width.replace('px', '')) + 30 + 'px'
        this.nextWidth = parseInt(this.obj.nextElementSibling.style.width.replace('px', '') - 30) + 'px'
      }
      window.addEventListener('mousemove', this.move)
      window.addEventListener('mouseup', this.up)
    },
    move(event) {
      let _width = parseInt(this.obj.style.width.replace('px', ''))
      _width += event.clientX - this.startX
      if (_width > parseInt(this.nextWidth.replace('px', '')) || _width < parseInt(this.prevWidth.replace('px', ''))) return
      const bl = ((_width - 30) * 100 / (this.$refs.slider.offsetWidth - 30)).toFixed(0) + '%'
      this.obj.childNodes[0].childNodes[0].innerText = bl
      this.startX = event.clientX
      this.obj.style.width = _width + 'px'
    },
    up(event) {
      this.sliderFlag = false
      window.removeEventListener('mousemove', this.move)
      window.removeEventListener('mouseup', this.up)

      const _index = parseInt(this.obj.getAttribute('index'))
      const bl = this.obj.childNodes[0].childNodes[0].innerText

      this.data[_index].bl = bl
      this.$emit('change', this.data)
    },
    getEle(obj) {
      const _this = this
      if (obj.getAttribute('class').indexOf('sbox') > -1) {
        _this.obj = obj
      } else {
        this.getEle(obj.parentNode)
      }
    }
  }
}
</script>
<style scoped>
.slider{
  width:400px;
  height:20px;
  border-radius: 10px 0 0 10px;
  background: #888;
  position: relative;
  margin:20px 0;
}
.sbox{
  position: absolute;
  left: 0;
  top:0;
  height:20px;
  width:100px;
  background: #0ff;
  border-radius: 10px;
}
.round-bg{
  width:30px;
  height:30px;
  border-radius: 15px;
  background: #fff;
  border:1px solid #ccc;
  position: absolute;
  right:0;
  top:-5px;
}
.round{
  width:20px;
  height:20px;
  border-radius: 12px;
  position: absolute;
  top:4px;
  left:4px;
  background: #0ff;

}
.bl{
  font-size:12px;
  position: absolute;
  top:-14px;
}
.jb{
  font-size:12px;
  position: absolute;
  bottom:-20px;
  white-space: nowrap;
}
.perfect{
    width:30px;
    position: absolute;
    top:-7px;
    right:-30px;
}
.perfect img{
    width:100%;
}
</style>