1、组件样式
2、使用
import cSlider from '@/components/c-slider/c-slider.vue'<div class="range"><cSlider v-model="cScale" @change="cScaleChange" :min="1" :max="10"/>
</div>
3、组件代码
<template><div class="slider-box" data-id="1"ref="sliderBox" @mousedown.stop.prevent="onMousedown($event)"@mouseup.stop.prevent="onMouseup"@mouseleave.stop.prevent="onMouseup"@mousemove.stop.prevent="onMousemove($event)"><div class="slider-wrap"><div class="slider-bar"data-id="1":style="{width: ((modelValue - min)*stepWidth)+'px'}"><spanclass="slider-btn":class="{active: sliderActive}"data-id="1"@mousedown.stop.prevent="onMousedown($event, true)":style="{left: ((modelValue - min)*stepWidth)+'px'}"><b>{{ modelValue }}</b></span></div></div></div>
</template><script>export default {model: {prop: 'modelValue',event: 'change'},props: {modelValue: {type: Number,default: 0},min: {type: Number,default: 0},max: {type: Number,default: 10},step: {type: Number,default: 1}},data() {return {rangeValue: 0,stepWidth: 0,sliderBox: null,moveAbled: false,mousePoint: null,sliderActive: false}},mounted() {// document.addEventListener('mouseup', this.onMouseup)// document.addEventListener('mouseleave', this.onMouseup)// this.$nextTick(() => {let _sliderBox = this.$refs['sliderBox'].getBoundingClientRect()this.sliderBox = {width: _sliderBox.width,height: _sliderBox.height,top: _sliderBox.top + document.documentElement.scrollTop,left: _sliderBox.left + document.documentElement.scrollLeft}this.stepWidth = this.sliderBox.width/(this.max-this.min)// console.log('xxx', _sliderBox, this.sliderBox)// })},beforeMount() {// document.removeEventListener('mouseup', this.onMouseup)// document.removeEventListener('mouseleave', this.onMouseup)},methods: {onMousemove(e) {if(this.moveAbled) {this.sliderActive = truelet d = e.pageX - this.mousePoint.pageXlet _val = Math.round(this.modelValue + d/this.stepWidth)if(_val < this.min) {_val = this.min} else if(_val > this.max) {_val = this.max}if(_val !== this.modelValue) {this.mousePoint = e}this.$emit('update:modelValue', _val)this.$emit('change')console.log('onMousemove', _val)}},onMouseup() {// console.log('onMouseup')this.moveAbled = falsethis.sliderActive = false},onMousedown(e, moveAbled) {console.log('onMousedown', this.stepWidth)if(moveAbled) {this.moveAbled = moveAbledthis.mousePoint = e} else {let d = e.pageX - this.sliderBox.leftlet _val = Math.round(this.min + d/this.stepWidth)if(_val < this.min) {_val = this.min} else if(_val > this.max) {_val = this.max}this.$emit('update:modelValue', _val)this.$emit('change')}},}
}</script><style lang="scss" scoped>.slider-box {width: 100%;height: 100%;display: flex;align-items: center;.range {position: absolute;top: 50%;left: 50%;width: 100%;transform: translate(-50%, -50%);opacity: 0.3;}.slider-wrap {position: relative;width: 100%;height: 3px;border-radius: 2px;background: #D9D9D9;cursor: pointer;.slider-bar {border-radius: 2px;height: 100%;background: #0256FF;.slider-btn {cursor: grab;position: absolute;top: 50%;left: 0;transform: translate(-50%, -50%);width: 10px;height: 10px;background: white;border-radius: 100%;box-shadow: 0 0 2px 2px #D6D6D6;&:hover, &.active {width: 15px;height: 15px;b {display: block;}}&::after {position: absolute;top: 50%;left: 50%;transform: translate(-50%, -50%);content: '';width: 4px;height: 4px;background: #0256FF;border-radius: 100%;}b {display: none;position: absolute;top: -10px;left: 50%;background: rgba(0, 0, 0, 0.3);color: white;font-size: 12px;padding: 0 5px;border-radius: 5px;transform: translate(-50%, -100%);&::after {position: absolute;bottom: 0px;left: 50%;transform: translate(-50%, 100%);content: '';width: 0;height: 0;border-top: 4px solid rgba(0, 0, 0, 0.3);border-left: 4px solid transparent;border-right: 4px solid transparent;border-right: 4px solid transparent;}}}}}}
</style>