vue实现拖动刻度
Vue 实现拖动刻度功能
核心思路
通过监听鼠标事件实现拖动交互 利用计算属性动态更新刻度位置 结合 CSS 过渡效果提升用户体验
基本实现步骤
创建可拖动滑块组件
<template>
<div class="slider-container">
<div
class="slider-track"
@mousedown="startDrag"
ref="track"
>
<div
class="slider-thumb"
:style="{ left: thumbPosition + 'px' }"
></div>
</div>
</div>
</template>
添加交互逻辑

export default {
data() {
return {
isDragging: false,
currentValue: 0,
maxValue: 100,
trackWidth: 300
}
},
computed: {
thumbPosition() {
return (this.currentValue / this.maxValue) * this.trackWidth
}
},
methods: {
startDrag(e) {
this.isDragging = true
document.addEventListener('mousemove', this.handleDrag)
document.addEventListener('mouseup', this.stopDrag)
this.updateValue(e)
},
handleDrag(e) {
if (!this.isDragging) return
this.updateValue(e)
},
stopDrag() {
this.isDragging = false
document.removeEventListener('mousemove', this.handleDrag)
document.removeEventListener('mouseup', this.stopDrag)
},
updateValue(e) {
const trackRect = this.$refs.track.getBoundingClientRect()
let newPosition = e.clientX - trackRect.left
newPosition = Math.max(0, Math.min(newPosition, trackRect.width))
this.currentValue = (newPosition / trackRect.width) * this.maxValue
}
}
}
样式优化
.slider-container {
width: 100%;
padding: 20px;
}
.slider-track {
position: relative;
height: 4px;
background: #ddd;
cursor: pointer;
}
.slider-thumb {
position: absolute;
width: 16px;
height: 16px;
background: #42b983;
border-radius: 50%;
top: -6px;
transform: translateX(-50%);
transition: left 0.1s ease;
}
高级功能扩展
添加刻度标记
<div class="slider-marks">
<span
v-for="mark in marks"
:key="mark.value"
:style="{ left: (mark.value / maxValue) * 100 + '%' }"
@click="jumpToMark(mark.value)"
>
{{ mark.label }}
</span>
</div>
双向绑定支持

props: {
value: Number
},
watch: {
value(newVal) {
this.currentValue = newVal
},
currentValue(newVal) {
this.$emit('input', newVal)
}
}
移动端适配
添加触摸事件支持
mounted() {
this.$refs.track.addEventListener('touchstart', this.startDrag)
},
methods: {
startDrag(e) {
this.isDragging = true
document.addEventListener('touchmove', this.handleDrag)
document.addEventListener('touchend', this.stopDrag)
this.updateValue(e.touches ? e.touches[0] : e)
}
}
性能优化
使用 requestAnimationFrame
handleDrag(e) {
if (!this.isDragging) return
requestAnimationFrame(() => {
this.updateValue(e)
})
}
添加防抖处理
import { debounce } from 'lodash'
methods: {
emitChange: debounce(function(value) {
this.$emit('change', value)
}, 100)
}






