微信小程序双向slider

0.413字数 627阅读 5605
图片来源:视觉中国
产品需要一个双向可以调节的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中的代码到项目中使用。
我的博客即将搬运同步至腾讯云+社区,邀请大家一同入驻:https://cloud.tencent.com/developer/support-plan?invite_code=150afwwtin5bq

推荐阅读更多精彩内容