Vue實現雙向滑動輸入條

本文實例為大傢分享瞭Vue實現雙向滑動輸入條的具體代碼,供大傢參考,具體內容如下

效果圖如下:

組件支持傳入最小值(min)最大值(max)的范圍,並可設置初始最小值(initialMin)和初始最大值(initialMax)

拖動滑塊調整最大最小值,並可點擊輸入條位置,切換數值

①創建滑動輸入條組件Slider.vue

<template>
  <div class="m-slider" ref="slider">
    <div class="u-slider-rail" @click="onClickPoint"></div>
    <div class="u-slider-track" @click="onClickPoint" :style="`left: ${left}px; right: auto; width: ${right - left}px;`"></div>
    <div class="u-slider-handle" ref="left" @mousedown="onLeftMouseDown" :style="`left: ${left}px; right: auto; transform: translateX(-50%);`"></div>
    <div class="u-slider-handle" ref="right" @mousedown="onRightMouseDown" :style="`left: ${right}px; right: auto; transform: translateX(-50%);`"></div>
  </div>
</template>
<script>
export default {
  name: 'Slider',
  props: {
    min: { // 滑動輸入條最小值
      type: Number,
      default: 0
    },
    max: { // 滑動輸入條最大值
      type: Number,
      default: 100
    },
    initialMin: { // 滑動輸入條初始最小值,默認在最左側
      type: Number,
      default: 0
    },
    initialMax: { // 滑動輸入條初始最大值,默認在最右側
      type: Number,
      default: 100
    }
  },
  data () {
    return {
      left: '', // 左滑塊距離滑動條左端的距離
      right: '', // 右滑動距離滑動條左端的距離
      width: '' // 滑動輸入條在頁面中的寬度
    }
  },
  mounted () {
    this.width = this.$refs.slider.clientWidth
    this.left = this.initialMin * this.width / this.max
    this.right = this.initialMax * this.width / this.max
  },
  computed: {
    low () {
      return Math.round(this.left / this.width * this.max)
    },
    high () {
      return Math.round(this.right / this.width * this.max)
    }
  },
  watch: {
    low (to, from) {
      this.$emit('lowChange', to) // 左滑塊對應數字回調
    },
    high (to, from) {
      this.$emit('highChange', to) // 右滑塊對應數字回調
    }
  },
  methods: {
    onClickPoint (e) { // 點擊滑動條,移動滑塊
      var offsetLeft = this.$refs.slider.offsetLeft // 滑動條左端距離屏幕左側的距離
      var moveX = e.clientX - offsetLeft
      if (moveX <= this.left) {
        this.left = moveX
      } else if (this.moveX >= this.right) {
        this.right = this.moveX
      } else {
        if ((moveX - this.left) < (this.right - moveX)) {
          this.left = moveX
        } else {
          this.right = moveX
        }
      }
    },
    onLeftMouseDown (e) { // 在滾動條上拖動左滑塊
      // 滑塊水平方向上距離屏幕左端的距離,減去滑塊距離滑動條最左端的距離:e.clientX - this.$refs.left.offsetLeft
      var offsetLeft = this.$refs.slider.offsetLeft // 滑動條左端距離屏幕左側的距離
      document.onmousemove = (e) => {
        var moveX = e.clientX - offsetLeft
        if (moveX < 0) {
          this.left = 0
        } else if (moveX >= this.right) {
          this.left = this.right
        } else {
          this.left = moveX
        }
      }
      document.onmouseup = (e) => {
        document.onmousemove = null
        document.onmouseup = null
      }
    },
    onRightMouseDown (e) { // 在滾動條上拖動右滑塊
      /// 滑塊水平方向上距離屏幕左端的距離,減去滑塊距離滑動條最左端的距離:e.clientX - this.$refs.left.offsetLeft
      var offsetLeft = this.$refs.slider.offsetLeft // 滑動條左端距離屏幕左側的距離
      console.log('offsetLeft:', offsetLeft)
      document.onmousemove = (e) => {
        var moveX = e.clientX - offsetLeft
        if (moveX > this.width) {
          this.right = this.width
        } else if (moveX <= this.left) {
          this.right = this.left
        } else {
          this.right = moveX
        }
      }
      document.onmouseup = (e) => {
        document.onmousemove = null
        document.onmouseup = null
      }
    }
  }
}
</script>
<style lang="less" scoped>
.m-slider {
  height: 4px;
  position: relative;
  cursor: pointer;
  touch-action: none;
  &:hover {
    .u-slider-rail { // 灰色未選擇滑動條背景色
      background: #E3E3E3;
    }
    .u-slider-track { // 藍色已選擇滑動條背景色
      background: #1890ff;
    }
  }
  .u-slider-rail { // 灰色未選擇滑動條背景色
    position: absolute;
    z-index: 99;
    height: 4px;
    width: 100%;
    background: #f5f5f5;
    border-radius: 2px;
    transition: background .3s;
  }
  .u-slider-track { // 藍色已選擇滑動條背景色
    background: #91d5ff;
    border-radius: 4px;
    position: absolute;
    z-index: 99;
    height: 4px;
    cursor: pointer;
    transition: background .3s;
  }
  .u-slider-handle { // 滑塊
    position: absolute;
    z-index: 999;
    width: 14px;
    height: 14px;
    margin-top: -7px;
    box-shadow: 0;
    background: #fff;
    border: 2px solid #91d5ff;
    border-radius: 50%;
    cursor: pointer;
    transition: border-color .3s,box-shadow .6s,transform .3s cubic-bezier(.18,.89,.32,1.28);
    &:hover {
      border-color: #1890ff;
    }
  }
}
</style>

②在要使用的頁面引入

<div class="m-num">
    <p class="u-num">{{ low }}</p>
    <p class="u-num">{{ high }}</p>
</div>
<div class="slider">
    <Slider
        :min="0"
        :max="100"
        :initialMin="low"
        :initialMax="high"
        @lowChange="lowChange"
        @highChange="highChange"
    />
</div>
import Slider from '@/components/Slider'
components: {
    Slider
}
data () {
    return {
        low: 20,
        high: 80
    }
}
lowChange (val) {
      this.low = val
      console.log('lowChange:', val)
},
highChange (val) {
      this.high = val
      console.log('highChange:', val)
}

以上就是本文的全部內容,希望對大傢的學習有所幫助,也希望大傢多多支持WalkonNet。

推薦閱讀: