产品需要一个双向可以调节的slider用来做微信小程序价格范围筛选,官方slider是单向的,这和iOS和安卓都是一样的,所以自定义了一个组件微信小程序双向slider。
双向slider.gif一个选择数值范围的slider,双向可以滑动,可以设置最大值,最小值,初始最小值,初始最大值,也可以设置滑块大小,具体使用如下:
先在要使用的地方的json文件中引入该组件
{
"usingComponents": {
"zy-slider": "../../component/zyslider"
},
"navigationBarTitleText": "zy-slider"
}
然后在wxml中使用
<view class="zy-slider">
<zy-slider minValue="0" maxValue="100" min="0" max="100" bind:lowValueChange="lowValueChangeAction"
bind:heighValueChange="heighValueChangeAction" />
</view>
参数说明:
min: Number/String slider 最小值
max: Number/String slider 最大值
minValue: Number/String slider 左边滑块初始位置
maxValue: Number/String slider 右边滑块初始位置
bind:lowValueChange : function 左边滑块回调 {lowValue:lowValue}
bind:heighValueChange : function 右边滑块回调 {heighValue:heighValue}
wxss:
.zy-slider {
margin: 60rpx;
}
主要实现思路:
一、滑块滑动手势可以使用catchtouchmove
方法捕获,但是拿到的是相对屏幕边框的px值,为了方便适配,我们需要转成rpx
1、在自定义组件的ready
(组件生命周期函数,在组件布局完成后执行,此时可以获取节点信息)方法中获取屏幕宽度,取得与750rpx的比例值
const getSystemInfo = util.wxPromisify(wx.getSystemInfo)
util.wxPromisify(wx.getSystemInfo)()
.then(res => {
let ratio = res.windowWidth / 750
that.setData({
ratio: ratio,
})
})
util.wxPromisify()
是官方函数的一个Promise封装函数,具体实现可以看demo源码。
2、获取当前slider视图的总宽度,此时获取的也是px值,加上比例值,转换成rpx单位
var query = wx.createSelectorQuery().in(this)
query.select(".container").boundingClientRect(function (res) {
}).exec()
二、为了简单起见,左边滑块使用最右边作为计数点,右边滑块最左边作为计数点,使用三条线作为slider主体,分别为left,body,right
1、使用相对定位依次布局
2、在取到slider视图总宽度后,在给滑块设置初始位置,此时
/**
* 设置左边滑块的值
*/
_propertyLeftValueChange: function () {
let minValue = this.data.minValue / this.data.max * this.data.bigLength
let min = this.data.min / this.data.max * this.data.bigLength
this.setData({
leftValue: minValue - min
})
},
/**
* 设置右边滑块的值
*/
_propertyRightValueChange: function () {
let right = this.data.maxValue / this.data.max * this.data.bigLength + this.data.sliderLength
this.setData({
rightValue: right
})
},
bigLength:slider总长度 = 视图总宽度 - 2 倍 滑块宽度
三、在滑动手势中重新给滑块设置位置
以左滑块为例:
/**
* 左边滑块滑动
*/
_minMove: function (e) {
let pagex = e.changedTouches[0].pageX / this.data.ratio - this.data.containerLeft - this.data.sliderLength / 2
if (pagex + this.data.sliderLength >= this.data.rightValue) {
pagex = this.data.rightValue - this.data.sliderLength
} else if (pagex <= 0) {
pagex = 0
}
this.setData({
leftValue: pagex
})
let lowValue = parseInt(pagex / this.data.bigLength * parseInt(this.data.max) + this.data.min)
var myEventDetail = { lowValue: lowValue }
this.triggerEvent('lowValueChange', myEventDetail)
},
tatio: 当前屏幕和750rpx之间的比例
containerLeft:当前slider视图距离屏幕左边距离
减去 1/2 的滑块的宽度是为了让滑块的位置和手指点的位置重合(我们的计数点事滑块边沿)
最终具体实现代码可以在GitHubzy-slider中查看。用来做微信小程序范围筛选还是不错的,可以直接拿Component中的代码到项目中使用。
网友评论
编码中。。。