需求:用户在滑块上能够左右滑动滑点,进行区间值的筛选
效果示例图
代码块
<template>
<view class="slider-wrap">
<view class="slider-start">{{ startValue }}</view>
<view style="width: 8px;"></view>
<view class="slider-progress">
<view class="slider-range" id="sliderRange" :style="{ width: sliderWidth + 'px' }">
<view class="rangeBox" :style="{ width: rangeWidth + 'px', left: minLeft + 'px' }"></view>
<view class="slider-lf" :style="{ left: minLeft + 'px' }" @touchstart="startTouchStartHandle" @touchmove="startTouchmoveHandle" @touchend="startTouchEndHandle">
<text></text>
</view>
<view class="slider-rg" :style="{ left: maxLeft + 'px' }" @touchstart="endTouchStartHandle" @touchmove="endTouchmoveHandle" @touchend="endTouchEndHandle">
<text></text>
</view>
</view>
</view>
<view style="width: 8px;"></view>
<view class="slider-end">{{ endValue }}</view>
</view>
</template>
<script>
let minInitX = 0;
let minInitLeft = 0;
let maxInitX = 0;
let maxInitLeft = 0;
export default {
data() {
return {
//默认值
defaultMin: 3,
defaultMax: 6,
//起始值
startValue: 2,
//结束值
endValue: 7,
//滑块的最大宽度
sliderWidth: 180,
//滑块之间最小间距,这个大小根据页面显示圆点大小设置
minSpace: 24,
//两个滑点之间的距离
rangeWidth: 180,
//左边滑点距离左边的距离
minLeft: 0,
//右边滑点距离左边的距离
maxLeft: 180
};
},
onShow() {
this.initSlider();
},
methods: {
/**
* 初始化数据
* **/
initSlider() {
//如果最大值小于等于最小值,就默认最大值100,最小值0
if (this.endValue <= this.startValue) {
this.startValue = 0;
this.endValue = 100;
}
if (this.defaultMin == 'null' || this.defaultMin == undefined || this.defaultMin == '') {
this.defaultMin = this.startValue;
}
if (this.defaultMax == 'null' || this.defaultMax == undefined || this.defaultMax == '') {
this.defaultMax = this.endValue;
}
//如果默认传值错误,就把默认传值设置成最大值,最小值
if (this.defaultMax <= this.defaultMin) {
this.defaultMin = this.startValue;
this.defaultMax = this.endValue;
}
if (this.defaultMin < this.startValue) {
this.defaultMin = this.startValue;
}
if (this.defaultMax > this.endValue) {
this.defaultMax = this.endValue;
}
this.minLeft = ((this.defaultMin - this.startValue) / (this.endValue - this.startValue)) * this.sliderWidth;
this.maxLeft = ((this.defaultMax - this.startValue) / (this.endValue - this.startValue)) * this.sliderWidth;
this.rangeWidth = this.maxLeft - this.minLeft;
},
/**
* min
* **/
startTouchStartHandle(e) {
//初始化鼠标开始拖拽的点击位置
minInitX = e.touches[0].clientX;
//获取滑块当前的位置
minInitLeft = e.currentTarget.offsetLeft;
},
startTouchmoveHandle(e) {
//获取鼠标移动后滑块应该移动到的位置
let nX = e.touches[0].clientX - minInitX + minInitLeft;
if (nX >= this.maxLeft - this.minSpace) {
nX = this.maxLeft - this.minSpace;
}
if (nX < 0) {
nX = 0;
}
this.minLeft = nX;
this.rangeWidth = this.maxLeft - this.minLeft;
},
startTouchEndHandle(e) {
this.changeRangeFun(this.minLeft, this.maxLeft);
e.stopPropagation();
},
/**
* max
* **/
endTouchStartHandle(e) {
//初始化鼠标开始拖拽的点击位置
maxInitX = e.touches[0].clientX;
//获取滑块当前的位置
maxInitLeft = e.currentTarget.offsetLeft;
},
endTouchmoveHandle(e) {
//获取鼠标移动后滑块应该移动到的位置
let nX = e.touches[0].clientX - maxInitX + maxInitLeft;
if (nX >= this.sliderWidth) {
nX = this.sliderWidth;
}
if (nX <= this.minLeft + this.minSpace) {
nX = this.minLeft + this.minSpace;
}
this.maxLeft = nX;
this.rangeWidth = this.maxLeft - this.minLeft;
},
endTouchEndHandle(e) {
this.changeRangeFun(this.minLeft, this.maxLeft);
e.stopPropagation();
},
/**
* 改变中间的距离线大小
* **/
changeRangeFun(min, max) {
const startValue = this.startValue;
const endValue = this.endValue;
let tempArr = [];
for (let i = startValue; i <= endValue; i++) {
tempArr.push(i);
}
//把滑动条距离分割
const sliderWidth = this.sliderWidth;
const part = sliderWidth / tempArr.length;
let minIndex = Math.trunc(min / part) - 1 < 0 ? 0 : Math.trunc(min / part) - 1;
let maxIndex = Math.trunc(max / part) - 1 < 1 ? 1 : Math.trunc(max / part) - 1;
const minValue = tempArr[minIndex];
const maxValue = tempArr[maxIndex];
console.log('[最终区间值]', minValue, maxValue);
this.defaultMin = minValue;
this.defaultMax = maxValue;
}
}
};
</script>
<style lang="scss" scoped>
// slider
.slider-wrap {
display: flex;
flex-direction: row;
.slider-start,
.slider-end {
width: 60px;
height: 36px;
background: #2c3b45;
border-radius: 18px;
font-size: 15px;
font-family: Source Han Sans CN;
font-weight: bold;
color: #ffffff;
display: flex;
justify-content: center;
align-items: center;
}
.slider-progress {
flex: 1;
display: flex;
flex-direction: row;
position: relative;
height: 36px;
align-items: center;
justify-content: center;
.slider-range {
width: 190px;
height: 10px;
background: #2c3b45;
border-radius: 4px;
position: relative;
.rangeBox {
width: 100%;
height: 10px;
background: linear-gradient(90deg, #1be6bd 0%, #00a8f6 100%);
border-radius: 4px;
position: absolute;
top: 0px;
}
.slider-lf {
width: 24px;
height: 24px;
background: linear-gradient(90deg, #1be6bd 0%, #00a8f6 100%);
border-radius: 50%;
position: absolute;
top: -7px;
display: flex;
justify-content: center;
align-items: center;
transform: translateX(-12px);
text {
width: 10px;
height: 10px;
background: #ffffff;
border-radius: 50%;
}
}
.slider-rg {
width: 24px;
height: 24px;
background: linear-gradient(90deg, #1be6bd 0%, #00a8f6 100%);
border-radius: 50%;
position: absolute;
top: -7px;
display: flex;
justify-content: center;
align-items: center;
transform: translateX(-12px);
text {
width: 10px;
height: 10px;
background: #ffffff;
border-radius: 50%;
}
}
}
}
}
</style>