【问题标题】:noUiSlider - double range slider with two inputs + vue.jsnoUiSlider - 具有两个输入 + vue.js 的双范围滑块
【发布时间】:2018-01-29 17:04:30
【问题描述】:

我想要一个带有两个输入的双范围滑块来控制范围。

就像这个: https://i.stack.imgur.com/8w0UI.png

我还需要将它与 vue.js 一起使用。

目前我有以下html:

   <div id="main">
        <br>
        <div id="slider"></div>
        <br>
        <input id="slider-input" v-model="third" v-on:change="updateSlider" />
    </div>

还有我的 JavaScript:

  var vue = new Vue({
    el: '#main',
    data: {
        minRange: 40,
        slider: {
            min: 0,
            max: 100,
            start: 40,
            step: 1
        },
        Slider: document.getElementById('slider')
    },
    methods: {
        updateSlider: function updateSlider() {
            this.Slider.noUiSlider.set(this.minRange);
        }
    },
    ready: function ready() {
        noUiSlider.create(this.Slider, {
            start: this.slider.start,
            step: this.slider.step,
            range: {
                'min': this.slider.min,
                'max': this.slider.max
            }
        });
    }
});

vue.$data.Slider.noUiSlider.on('update', function(values, handle) {
    vue.$data.minRange = values[handle];
});

有了这个,我可以有一个带有一个处理程序的范围滑块。我可以拖动处理程序,更新输入中的值,还可以写入一些新值并更新处理程序位置 (UI)。

现在,我想添加另一个处理程序,并立即使用我现有的处理程序执行我能够执行的所有功能。

我该怎么做? (复制输入,添加data.maxRange,然后...?

谢谢。

【问题讨论】:

    标签: javascript input vue.js nouislider


    【解决方案1】:

    这是您需要在滑块端进行的调整:

    使用两个句柄:

    start: [this.slider.startMin, this.slider.startMax]
    

    更新事件必须同时处理这两个:

    vue.$data[handle ? 'maxRange' : 'minRange'] = values[handle];
    

    在您的updateSlider 函数中:

    this.Slider.noUiSlider.set([this.minRange, this.maxRange]);
    

    【讨论】:

    • 非常感谢。我快到了,但你的帮助是关键。
    • 现在我面临另一个问题:这个脚本使用的是过时的 vue 版本。使用更新的版本,不会触发 ready 方法。我已经更改为已安装但仍然无法正常工作。无法绘制滑块。有什么线索吗?
    【解决方案2】:

    这是我在需要同样的东西后想出的一个相当简单的答案。我查看了同一个滑块,并决定根据我找到的一个 js 滑块提出我自己的滑块。下面是小提琴。

    js fiddle dual range slider in vuejs

    var app = new Vue({
      el: '#app',
      data: {
        minPrice: "500",
        maxPrice: "50000"
      },
      methods: {
        slider: function() {
          if (this.minPrice > this.maxPrice) {
            var tmp = this.maxPrice;
            this.maxPrice = this.minPrice;
            this.minPrice = tmp;
          }
        }
      }
    })
    .range-slider {
      width: 300px;
      margin: auto;
      text-align: center;
      position: relative;
      height: 6em;
    }
    
    .range-slider svg,
    .range-slider input[type=range] {
      position: absolute;
      left: 0;
      bottom: 0;
    }
    
    input[type=number] {
      border: 1px solid #ddd;
      text-align: center;
      font-size: 1.6em;
      -moz-appearance: textfield;
    }
    
    input[type=number]::-webkit-outer-spin-button,
    input[type=number]::-webkit-inner-spin-button {
      -webkit-appearance: none;
    }
    
    input[type=number]:invalid,
    input[type=number]:out-of-range {
      border: 2px solid #ff6347;
    }
    
    input[type=range] {
      -webkit-appearance: none;
      width: 100%;
    }
    
    input[type=range]:focus {
      outline: none;
    }
    
    input[type=range]:focus::-webkit-slider-runnable-track {
      background: #2497e3;
    }
    
    input[type=range]:focus::-ms-fill-lower {
      background: #2497e3;
    }
    
    input[type=range]:focus::-ms-fill-upper {
      background: #2497e3;
    }
    
    input[type=range]::-webkit-slider-runnable-track {
      width: 100%;
      height: 5px;
      cursor: pointer;
      animate: 0.2s;
      background: #2497e3;
      border-radius: 1px;
      box-shadow: none;
      border: 0;
    }
    
    input[type=range]::-webkit-slider-thumb {
      z-index: 2;
      position: relative;
      box-shadow: 0px 0px 0px #000;
      border: 1px solid #2497e3;
      height: 18px;
      width: 18px;
      border-radius: 25px;
      background: #a1d0ff;
      cursor: pointer;
      -webkit-appearance: none;
      margin-top: -7px;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.js"></script>
    <div id="app">
      <div class="range-slider">
        <span @change="slider">from <input v-model.number="minPrice" type="number"  min="0" max="120000"/> to <input  v-model.number="maxPrice" type="number"  min="0" max="120000"/></span>
        <input @change="slider" v-model.number="minPrice" min="0" max="120000" step="500" type="range" />
        <input @change="slider" v-model.number="maxPrice" min="0" max="120000" step="500" type="range" />
        <svg width="100%" height="24">
                              <line x1="4" y1="0" x2="300" y2="0" stroke="#444" stroke-width="12" stroke-dasharray="1 28"></line>
                            </svg>
      </div>
    </div>

    【讨论】:

    • 不,它没有,签入 FF 72+。我看到带有文本“500”的输入字段和点击时没有响应的大滑块
    【解决方案3】:

    我认为不可能调整该组件并使其成为范围滑块。

    有一个 JQuery UI 组件可以管理范围: https://jqueryui.com/slider/#range

    而且,可以包装 JQuery UI 组件,让它们在 Vue 环境中工作: https://vuejsdevelopers.com/2017/05/20/vue-js-safely-jquery-plugin/

    如果您可以使两者一起工作,它将满足您的要求。此外,您必须将 JQuery 和 JQuery UI 捆绑为依赖项。

    【讨论】:

    • noUiSlider (refreshless.com/nouislider) 是一种无需依赖即可创建此类滑块的工具。我链接的屏幕截图来自他们网站上的一个工作示例。我的问题完全出在工具上。这是可能的,我不需要任何依赖。谢谢你的回答。
    猜你喜欢
    • 2023-02-09
    • 1970-01-01
    • 2021-08-22
    • 1970-01-01
    • 1970-01-01
    • 2021-12-08
    • 2014-09-29
    • 1970-01-01
    • 2018-09-22
    相关资源
    最近更新 更多