当前位置:首页 > VUE

vue实现滑块区间

2026-02-18 07:05:46VUE

Vue 实现滑块区间组件

使用原生 input range 实现

通过两个 input[type="range"] 元素实现基础的双滑块功能。这种方法简单直接,适合基础需求。

<template>
  <div class="range-slider">
    <input 
      type="range" 
      v-model="minValue" 
      :min="min" 
      :max="max" 
      @input="updateMin"
    >
    <input 
      type="range" 
      v-model="maxValue" 
      :min="min" 
      :max="max" 
      @input="updateMax"
    >
    <div>当前范围: {{ minValue }} - {{ maxValue }}</div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      min: 0,
      max: 100,
      minValue: 30,
      maxValue: 70
    }
  },
  methods: {
    updateMin(e) {
      this.minValue = Math.min(e.target.value, this.maxValue)
    },
    updateMax(e) {
      this.maxValue = Math.max(e.target.value, this.minValue)
    }
  }
}
</script>

<style>
.range-slider {
  width: 300px;
  margin: 20px;
}
input[type="range"] {
  width: 100%;
  margin: 10px 0;
}
</style>

使用第三方库 vue-slider-component

对于更复杂的需求,推荐使用专门的滑块组件库。vue-slider-component 是一个功能丰富的 Vue 滑块组件。

安装依赖:

npm install vue-slider-component --save

基本用法:

<template>
  <div>
    <vue-slider 
      v-model="value" 
      :min="0" 
      :max="100" 
      :interval="10"
      :drag-on-click="true"
      :tooltip="'always'"
      :marks="marks"
    />
  </div>
</template>

<script>
import VueSlider from 'vue-slider-component'
import 'vue-slider-component/theme/default.css'

export default {
  components: {
    VueSlider
  },
  data() {
    return {
      value: [20, 80],
      marks: [
        { label: '0', value: 0 },
        { label: '50', value: 50 },
        { label: '100', value: 100 }
      ]
    }
  }
}
</script>

自定义滑块组件

如果需要完全自定义样式和行为,可以创建自己的滑块组件。

<template>
  <div class="custom-slider">
    <div class="slider-track">
      <div 
        class="slider-range" 
        :style="rangeStyle"
      ></div>
      <div 
        class="slider-thumb left-thumb" 
        :style="leftThumbStyle"
        @mousedown="startDrag('left')"
      ></div>
      <div 
        class="slider-thumb right-thumb" 
        :style="rightThumbStyle"
        @mousedown="startDrag('right')"
      ></div>
    </div>
  </div>
</template>

<script>
export default {
  props: {
    min: { type: Number, default: 0 },
    max: { type: Number, default: 100 },
    value: { type: Array, default: () => [30, 70] }
  },
  data() {
    return {
      activeThumb: null,
      currentValue: [...this.value]
    }
  },
  computed: {
    rangeStyle() {
      const left = ((this.currentValue[0] - this.min) / (this.max - this.min)) * 100
      const right = 100 - ((this.currentValue[1] - this.min) / (this.max - this.min)) * 100
      return {
        left: `${left}%`,
        right: `${right}%`
      }
    },
    leftThumbStyle() {
      return {
        left: `${((this.currentValue[0] - this.min) / (this.max - this.min)) * 100}%`
      }
    },
    rightThumbStyle() {
      return {
        left: `${((this.currentValue[1] - this.min) / (this.max - this.min)) * 100}%`
      }
    }
  },
  methods: {
    startDrag(thumb) {
      this.activeThumb = thumb
      document.addEventListener('mousemove', this.handleDrag)
      document.addEventListener('mouseup', this.stopDrag)
    },
    handleDrag(e) {
      if (!this.activeThumb) return

      const slider = this.$el.querySelector('.slider-track')
      const rect = slider.getBoundingClientRect()
      let position = (e.clientX - rect.left) / rect.width
      position = Math.max(0, Math.min(1, position))
      const value = Math.round(position * (this.max - this.min) + this.min)

      if (this.activeThumb === 'left') {
        this.currentValue[0] = Math.min(value, this.currentValue[1])
      } else {
        this.currentValue[1] = Math.max(value, this.currentValue[0])
      }

      this.$emit('input', [...this.currentValue])
    },
    stopDrag() {
      this.activeThumb = null
      document.removeEventListener('mousemove', this.handleDrag)
      document.removeEventListener('mouseup', this.stopDrag)
    }
  }
}
</script>

<style>
.custom-slider {
  width: 300px;
  margin: 20px;
}
.slider-track {
  position: relative;
  height: 4px;
  background: #ddd;
  border-radius: 2px;
}
.slider-range {
  position: absolute;
  height: 100%;
  background: #42b983;
  border-radius: 2px;
}
.slider-thumb {
  position: absolute;
  width: 16px;
  height: 16px;
  background: #fff;
  border: 2px solid #42b983;
  border-radius: 50%;
  top: -6px;
  transform: translateX(-50%);
  cursor: pointer;
}
</style>

响应式设计考虑

确保滑块在不同设备上都能良好工作,可以添加响应式样式:

@media (max-width: 768px) {
  .custom-slider {
    width: 100%;
    padding: 0 10px;
  }
  .slider-thumb {
    width: 24px;
    height: 24px;
    top: -10px;
  }
}

无障碍访问

为提升可访问性,可以添加 ARIA 属性:

vue实现滑块区间

<div 
  class="slider-thumb left-thumb" 
  role="slider"
  aria-valuemin="min"
  aria-valuemax="max"
  aria-valuenow="currentValue[0]"
  tabindex="0"
></div>

这些方法提供了从简单到复杂的 Vue 滑块区间实现方案,可以根据项目需求选择合适的方式。

标签: 区间滑块
分享给朋友:

相关文章

vue实现弧形滑块

vue实现弧形滑块

实现弧形滑块的基本思路 在Vue中实现弧形滑块需要结合SVG或Canvas绘制弧形轨道,并通过动态计算滑块位置实现交互效果。核心在于将线性输入值映射到弧形路径上。 使用SVG实现弧形轨道 通过SVG…

js实现拖滑块

js实现拖滑块

实现拖滑块的基本思路 使用HTML、CSS和JavaScript创建一个可拖动的滑块。滑块通常由一个轨道和一个可拖动的滑块组成,通过监听鼠标事件实现拖动功能。 HTML结构 创建一个简单的滑块结构,…

vue实现登录的滑块

vue实现登录的滑块

实现登录滑块验证的基本思路 在Vue中实现登录滑块验证通常涉及前端交互逻辑和后端验证。滑块验证的核心是用户拖动滑块到指定位置完成验证,确保操作由真人完成。 前端组件结构 创建一个滑块验证组件,包含以…

vue实现时间滑块

vue实现时间滑块

实现时间滑块的基本思路 在Vue中实现时间滑块可以通过结合原生HTML的<input type="range">和Vue的数据绑定特性。核心是利用v-model双向绑定滑块值,并通过计算属…

vue实现阶梯区间价格

vue实现阶梯区间价格

实现阶梯区间价格 在Vue中实现阶梯区间价格功能,通常需要根据用户选择的数量或范围,动态计算对应的价格。以下是实现方法: 数据准备 定义阶梯价格数据,通常是一个数组,每个元素包含区间范围和对应价格:…