前言
官方自带的以及vant weapp组件都是只有单向的slider
双向的slider,网上抄了几篇文章,代码量巨大而且还有各种bug,相当难用,chatGPT写的也没法用,没办法,只能自己手写一个了
实现了的几个细节(别的文章里大部分存在这些bug)
一、当左滑块拖动的范围超过父容器最左边时,赋值为0;
右边同理赋值为最大值
二、当右滑块向左滑,并且试图越过左滑块时,右边赋值与左边相等,并且无法越过左边(最多就是两个圆圈紧挨着)
三、可重置
父组件代码(很简单)
<my-slider bind:submit="getAge" ></my-slider>
getAge(e){
this.setData({
min: e.detail.min,
max: e.detail.max,
})
}
子组件代码(最重要的部分)
<view class="slider-background">
<view class="slider" style="padding-left: {{pdLeft}}rpx;padding-right: {{pdRight}}rpx;">
<view class="slider-circle" bindtouchstart="touchStart1" bindtouchmove="touchMove1" bindtouchend="touchEnd1"></view>
<view class="main-slider"></view>
<view class="slider-circle" bindtouchstart="touchStart2" bindtouchmove="touchMove2" bindtouchend="touchEnd2"></view>
</view>
</view>
.slider-background{
width: 684rpx;
margin: 0 auto;
display: flex;
align-items: center;
height: 8rpx;
background-color: rgb(228, 228, 228);
}
.slider{
width: 100%;
padding: 0;
display: flex;
align-items: center;
}
.slider .main-slider{
width: calc(100% - 84rpx);
height: 8rpx;
background-color: blue;
}
.slider .slider-circle{
width: 42rpx;
height: 42rpx;
background-color: #fff;
border-radius: 50%;
box-shadow: 0 2rpx 4rpx rgba(0, 0, 0, 0.5);
}
// components/slider/index.js
Component({
// 使用全局样式
options: {
addGlobalClass: true
},
lifetimes: {
attached: function() {
// 在组件实例进入页面节点树时执行
const res = wx.getSystemInfoSync()
this.setData({
ratio: 750 / res.windowWidth
})
},
detached: function() {
// 在组件实例被从页面节点树移除时执行
},
},
/**
* 组件的属性列表
*/
properties: {
},
/**
* 组件的初始数据
*/
data: {
pdLeft: 0, // 左边滑块的位置
pdRight: 0, // 右边滑块的位置
ratio: 2,
startX1: 0, //计算左滑块初始位置离屏幕左边的距离
startX2: 0, //计算右滑块初始位置离屏幕右边的距离
},
/**
* 组件的方法列表
*/
methods: {
touchStart1(e){
// console.log("e0", e.touches[0].clientX);
if(!this.data.startX1){
this.setData({
startX1: e.touches[0].clientX
})
}
},
touchMove1(e){
// console.log("eeee1", e.touches[0].clientX);
let x = (e.touches[0].clientX - this.data.startX1) * this.data.ratio
let v = x >= 0 ? x : 0 //不能超过父容器最左边
if(v + this.data.pdRight >= 600){ //右边的滑块越过左边时
v = 600 - this.data.pdRight
}
this.setData({
pdLeft: v
})
this.triggerEvent('submit', {
min: Math.round(v/5),
})
// console.log("this.data.pdLeft", this.data.pdLeft);
},
touchEnd1(){},
touchStart2(e){
// console.log("e0", e.touches[0].clientX);
if(!this.data.startX2){
this.setData({
startX2: e.touches[0].clientX
})
}
},
touchMove2(e){
// console.log("eeee2", e.touches[0].clientX);
let x = (this.data.startX2 - e.touches[0].clientX) * this.data.ratio
let v = x >= 0 ? x : 0 //不能超过父容器最右边
if(v + this.data.pdLeft >= 600){ //右边的滑块越过左边时
v = 600 - this.data.pdLeft
}
this.setData({
pdRight: v
})
this.triggerEvent('submit', {
max: Math.round((600-v)/5),
})
// console.log("this.data.pdRight", this.data.pdRight);
},
touchEnd2(){},
reset(){
this.setData({
pdLeft: 0,
pdRight: 0,
startX1: 0,
startX2: 0,
})
this.triggerEvent('submit', {
min: 0,
max: 120
})
},
}
})
备注
看js文件可以看到,我是直接在里面写了0到120,如果要设计成最小值最大值从父组件传进来可以自己稍作修改。
其他参数同理(颜色,圆圈样式等等)
存在的问题
父容器写死了width: 684rpx;减去两个圆圈刚好是600rpx;所以js里很多计算都是直接用600进行计算。文章来源:https://www.toymoban.com/news/detail-482306.html
优化方案:可以改成父容器里写width: 100%;然后在js里先调用方法来获取他的宽度文章来源地址https://www.toymoban.com/news/detail-482306.html
到了这里,关于【微信原生小程序】手写双向slider滑块的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!