
圖片來源:視覺中國
產(chǎn)品需要一個(gè)雙向可以調(diào)節(jié)的slider用來做微信小程序價(jià)格范圍篩選,官方slider是單向的,這和iOS和安卓都是一樣的,所以自定義了一個(gè)組件微信小程序雙向slider。

雙向slider.gif
一個(gè)選擇數(shù)值范圍的slider,雙向可以滑動(dòng),可以設(shè)置最大值,最小值,初始最小值,初始最大值,也可以設(shè)置滑塊大小,具體使用如下:
先在要使用的地方的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>
參數(shù)說明:
min: Number/String slider 最小值
max: Number/String slider 最大值
minValue: Number/String slider 左邊滑塊初始位置
maxValue: Number/String slider 右邊滑塊初始位置
bind:lowValueChange : function 左邊滑塊回調(diào) {lowValue:lowValue}
bind:heighValueChange : function 右邊滑塊回調(diào) {heighValue:heighValue}
wxss:
.zy-slider {
margin: 60rpx;
}
主要實(shí)現(xiàn)思路:
一、滑塊滑動(dòng)手勢可以使用catchtouchmove方法捕獲,但是拿到的是相對屏幕邊框的px值,為了方便適配,我們需要轉(zhuǎn)成rpx
1、在自定義組件的ready(組件生命周期函數(shù),在組件布局完成后執(zhí)行,此時(shí)可以獲取節(jié)點(diǎn)信息)方法中獲取屏幕寬度,取得與750rpx的比例值
const getSystemInfo = util.wxPromisify(wx.getSystemInfo)
util.wxPromisify(wx.getSystemInfo)()
.then(res => {
let ratio = res.windowWidth / 750
that.setData({
ratio: ratio,
})
})
util.wxPromisify()是官方函數(shù)的一個(gè)Promise封裝函數(shù),具體實(shí)現(xiàn)可以看demo源碼。
2、獲取當(dāng)前slider視圖的總寬度,此時(shí)獲取的也是px值,加上比例值,轉(zhuǎn)換成rpx單位
var query = wx.createSelectorQuery().in(this)
query.select(".container").boundingClientRect(function (res) {
}).exec()
二、為了簡單起見,左邊滑塊使用最右邊作為計(jì)數(shù)點(diǎn),右邊滑塊最左邊作為計(jì)數(shù)點(diǎn),使用三條線作為slider主體,分別為left,body,right
1、使用相對定位依次布局
2、在取到slider視圖總寬度后,在給滑塊設(shè)置初始位置,此時(shí)
/**
* 設(shè)置左邊滑塊的值
*/
_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
})
},
/**
* 設(shè)置右邊滑塊的值
*/
_propertyRightValueChange: function () {
let right = this.data.maxValue / this.data.max * this.data.bigLength + this.data.sliderLength
this.setData({
rightValue: right
})
},
bigLength:slider總長度 = 視圖總寬度 - 2 倍 滑塊寬度
三、在滑動(dòng)手勢中重新給滑塊設(shè)置位置
以左滑塊為例:
/**
* 左邊滑塊滑動(dòng)
*/
_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: 當(dāng)前屏幕和750rpx之間的比例
containerLeft:當(dāng)前slider視圖距離屏幕左邊距離
減去 1/2 的滑塊的寬度是為了讓滑塊的位置和手指點(diǎn)的位置重合(我們的計(jì)數(shù)點(diǎn)事滑塊邊沿)
最終具體實(shí)現(xiàn)代碼可以在GitHubzy-slider中查看。用來做微信小程序范圍篩選還是不錯(cuò)的,可以直接拿Component中的代碼到項(xiàng)目中使用。
我的博客即將搬運(yùn)同步至騰訊云+社區(qū),邀請大家一同入駐:https://cloud.tencent.com/developer/support-plan?invite_code=150afwwtin5bq
賞我一個(gè)贊吧~~~