栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > Web开发 > Vue.js

VUE开发一个组件——Vue Slider 双向两滑块限定区域

Vue.js 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

VUE开发一个组件——Vue Slider 双向两滑块限定区域

前言

很多现有的vue slider组件都是单个滑块,一次业务需要,只能自己动手来一个了。双向两滑块限定区域,实现过滤功能了。

看起来,是不是还挺有趣的,限定时间区域,温度,数量等等,都是不错的组件。实现起来,也不难的。

页面部分

ruler是整个滑块区域,下面的date只是展示有的。并写了一个简单的filter过滤器,不明白过滤器的同学,请看《vue 内置过滤器总结(附加自定义过滤器)》
startbar、endbar分别就是两个滑块了。上面添加了touchstart和touchmove事件,用于监听滑动的位置,计算值。

{{startStep | hoursFilter}}
{{endStep | hoursFilter}}
#c-slider{
  .clearfix{
    &:after{
      content: '';
      display: block;
      clear: both;
    }
  }
  .slider{
    margin: auto;
    width: 80%;
    .date{
      color: #333;
      font-size: .7rem;
      margin-top: 1rem;
      .fl{
 float: left;
      }
      .fr{
 float: right;
      }
    }
    .ruler{
      background: #879BAE ;
      height: 1px;
      position:  relative;
      margin-top: 75px;
      .bar{
 position: absolute;
 top: -.5rem;
 height: 1rem;
 width: 1rem;
 border-radius: 100%;
 background: #D8D8D8;
 font-size:  0.3rem;
 line-height:  0.65rem;
 text-align:  center;
      }
      .startbar{
 left: 0;
      }
      .endbar{
 right: 0;
 background: #879BAE;
      }
    }
  }
}

JS事件

下方注释很详细,就简单的介绍一下吧

默认值
data () {
  return {
    $ruler: '', // 滑竿
    $bar: '', // 左侧滑块
    $endbar: '', // 右侧滑块
    startX: '', // 左侧滑块位置
    endX: '', // 右侧滑块位置
    step: '', // 滑竿在限定范围内可以分多少步
    intervalStart: 0, 
    intervalEnd: 24,
    startStep: 0,
    endStep: 24,
    amountW: '' //  滑竿多长距离
  }
}

初始化

Vue.nextTick用于延迟执行一段代码,否则初始化initSlider很容易找不到元素。同时我们用vm.$refs.xxx来获取元素。
元素上面记得添加ref属性。

created() {
  const vm = this;
  vm.$nextTick(() => {
    vm.initSlider();
  })
},
methods: {
  initSlider(){
    const vm = this;
    vm.$ruler = vm.$refs.ruler;
    vm.$bar = vm.$refs.bar;
    vm.$endbar = vm.$refs.endbar;
    // 滑竿多长距离
    vm.amountW = vm.$ruler.clientWidth - vm.$bar.clientWidth; 
    // 总共多少步
    vm.step = vm.amountW / (vm.intervalEnd - vm.intervalStart);
  }
}

事件
methods: {
  startTouchstart(e) {
    const vm = this;
    // 开始滑动时滑块的位置
    vm.startX = e.touches[0].pageX;
  },
  startTouchmove(e) {
    const vm = this;

    // 滑动距离=当前滑块x距离-最开始滑块距离
    let slidedis = e.touches[0].pageX - vm.$ruler.offsetLeft; 

    // 滑动距离小于0 或者大于滑竿的宽度,return掉
    if (slidedis < 0 || slidedis > vm.amountW) {
      return;
    }
    let ste = Math.round(slidedis / vm.step);
    if ((ste + vm.intervalStart) >= vm.endStep) {
      return;
    }
    vm.startStep = ste + vm.intervalStart;
    vm.$bar.style.left = (ste * vm.step) + 'px'
  },
  endTouchstart(e) {
    const vm = this;
    // 开始滑动时滑块的位置
    vm.endX = e.touches[0].pageX; 
  },
  endTouchmove(e) {
    const vm = this;
    // 滑动距离=当前滑块x距离-最开始滑块距离
    let slidedis = e.touches[0].pageX - vm.$ruler.offsetLeft; 

    if (slidedis < 0 || slidedis > vm.amountW) {
      return;
    }
    let ste = Math.round(slidedis / vm.step);

    if (vm.startStep >= (ste + vm.intervalStart)) {
      return;
    }
    vm.endStep = ste + vm.intervalStart;

    if(vm.endStep==24){
      vm.$endbar.style.left = ''
      vm.$endbar.style.right = '0px'
    }else{
      vm.$endbar.style.left = (ste * vm.step) + 'px'
    }
  }
}

有兴趣的同学,可以继续开发,优化等等。

源码地址:vue-c-slider

转载请注明:文章转载自 www.mshxw.com
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号