zoukankan      html  css  js  c++  java
  • 基于mpvue实现微信小程序区间选择(range-slider)

    微信小程序实现区间选择,时间范围选择,可设置步长

    API

    slider props
    参数 必选 类型 默认值 说明
    disabled false Boolean false 是否禁用
    max false Number 24 最大值
    min false Number 0 最小值
    value false Number 0 默认值
    step false Number 0.5 步长
    type false String time 组件类型

    组件截图

    Talk is cheap. Show me the code

    <template>
       <div class="range-slider" @click="onClick">
         <div class="range-slider-wrap">
           <div class="range-slider-bar" :style="atTrackStyle"></div>
           <div class="range-slider-button" @touchmove="onTouchMove($event,'aX')" @touchend="onTouchEnd($event, 'aX')" @touchcancel="onTouchEnd" :style="{left: aX + '%'}">
             <div class="range-slider-value">{{range[0]}}</div>
           </div>
           <div class="range-slider-button" @touchmove="onTouchMove($event,'bX')" @touchend="onTouchEnd($event, 'bX')" @touchcancel="onTouchEnd" :style="{left: bX + '%'}">
             <div class="range-slider-value">{{range[1]}}</div>
           </div>
         </div>
       </div>
    </template>
    <script>
    export default {
        props: {
            disabled: {
                type: Boolean,
                default: false
            },
            max: {
                type: Number,
                default: 24
            },
            min: {
                type: Number,
                default: 0
            },
            step: {
                type: Number,
                default: 0.5
            },
            value: {
                type: Array,
                default: () => [0, 0]
            },
            type: {
                type: String,
                default: 'time'
            }
        },
        data () {
            return {
                aX: 0,
                bX: 0,
                 0, // range宽度
                left: 0, // range 到屏幕左边的距离
                deltaValue: this.max - this.min,
                currentSlider: '',
                currentValue: [0, 0]
            };
        },
        computed: {
            atTrackStyle () {
                const { aX, bX } = this;
                const smallerX = Math.min(aX, bX);
                const deltaX = Math.abs(aX - bX);
                return `left:${smallerX}%;${deltaX}%`;
            },
            range () {
                let range = this.currentValue;
                return this.type === 'time' ? range.map(item => this.formatHoursToUT(item)) : range;
            }
        },
        methods: {
            onTouchMove (event, sliderName) {
                event = event.mp;
                if (this.disabled) { return; }
                const clientX = event.touches[0].clientX;
                this.setSliderValue(sliderName, clientX - this.left, 'onChange');
            },
            onTouchEnd (sliderName) {
                if (this.disabled) { return; }
                this.currentSlider = sliderName;
                this.triggerEvent('onAfterChange');
            },
            setSliderValue (sliderName, targetValue, funcName) {
                const distance = Math.min(Math.max(targetValue, 0), this.width);
                const sliderValue = Math.floor((distance / this.width) * 100);
                if (funcName) {
                    this.triggerEvent(funcName);
                }
                if (sliderName === 'bX' && sliderValue <= this.aX) {
                    this[sliderName] = this.aX;
                    return;
                }
                if (sliderName === 'aX' && sliderValue >= this.bX) {
                    this[sliderName] = this.bX;
                    return;
                }
                this[sliderName] = sliderValue;
            },
            triggerEvent (funcName) {
                const { aX, bX } = this;
                const steps = Math.round(this.deltaValue / this.step);
                const a = Math.round((aX / 100) * steps) * this.step + this.min;
                const b = Math.round((bX / 100) * steps) * this.step + this.min;
                const result = [a, b].sort((x, y) => x - y);
                console.log(aX, bX, result, '位移');
                this.currentValue = result;
                this.$emit(funcName, result);
            },
            onClick (event) {
                if (this.currentSlider && !this.disabled) {
                    let sliderValue = 0;
                    const detail = event.touches[0].clientX;
                    sliderValue = detail - this.left;
                    this.setSliderValue(this.currentSlider, sliderValue, 'onChange');
                }
            },
            setValue (value) {
                this.aX = Math.round(((value[0] - this.min) / this.deltaValue) * 100);
                this.bX = Math.round(((value[1] - this.min) / this.deltaValue) * 100);
            },
            formatHoursToUT (value) {
                value = value * 3600;
                let result = parseInt(value);
                let h = Math.floor(result / 3600) < 10 ? '0' + Math.floor(result / 3600) : Math.floor(result / 3600);
                let m = Math.floor((result / 60 % 60)) < 10 ? '0' + Math.floor((result / 60 % 60)) : Math.floor((result / 60 % 60));
                result = `${h}:${m}`;
                return result;
            },
            getRect (selector, all) {
                return new Promise(resolve => {
                    wx.createSelectorQuery()[all ? 'selectAll' : 'select'](selector)
                        .boundingClientRect(rect => {
                            if (all && Array.isArray(rect) && rect.length) {
                                resolve(rect);
                            }
                            if (!all && rect) {
                                resolve(rect);
                            }
                        })
                        .exec();
                });
            }
        },
        mounted () {
            const { value } = this;
            this.getRect('.range-slider')
                .then(rect => {
                    console.log(rect, value);
                    this.width = Math.round(rect.width);
                    this.left = Math.round(rect.left);
                    this.setValue(value);
                });
        }
    };
    </script>
    <style lang="less">
    .range-slider {
       80%;
      margin-left: 10%;
      .range-slider-wrap {
        position:relative;
        background-color:#EFEFEF;
         100%;
        height: 12rpx;
        border-radius: 8rpx;
        margin: 50rpx 0;
        vertical-align: middle;
        cursor: pointer;
      }
      .range-slider-bar {
        position:absolute;
        background-color:#FBBB00;
        height: 12rpx;
      }
      .range-slider-button {
        position:absolute;
        top:50%;
        transform:translate3d(-50%,-50%,0);
         40rpx;
        height: 40rpx;
        background-color:#fff;
        border: 4rpx solid #DDDDDD;
        box-shadow: 0 2rpx 8rpx 0 rgba(211,211,211,0.68);
        border-radius: 20rpx;
        & .range-slider-value {
          position: absolute;
          top: -70rpx;
          left: 50%;
          transform: translateX(-50%);
          font-size: 40rpx;
          color: #9EA4A1;
        }
      }
    }
    </style>
    
    
    
    
  • 相关阅读:
    C#中将结构类型数据存储到二进制文件中方法
    常用的20个在线工具类网站清单
    PyQt:开发小工具
    PyQt:使用QtDesigner设计界面
    经营策略
    Xmind 8 update 9 破解
    AI: 百度AI实战教学
    DRF:djangorestframework从入门到精通
    python:requests库发送参数+文件
    python:关于postman中生成的基于requests库的接口代码
  • 原文地址:https://www.cnblogs.com/Lewiskycc/p/11550675.html
Copyright © 2011-2022 走看看