首頁 > 軟體

Vue實現雙向滑動輸入條

2022-03-03 13:00:37

本文範例為大家分享了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)
}

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援it145.com。


IT145.com E-mail:sddin#qq.com