javascriptvue.jsnouislider

Vue.js 2.x.x + noUiSlider: lifecycle and slider creation


I want a double range slider with two inputs in order to control the range.

Just like this one: https://i.sstatic.net/8w0UI.png

I also need to get it alongside with vue.js.

I've acomplished this goal with vue 1.0.19.

Now I want to do it with vue 2.5.13 and it doesn't work at all.

I thought this was due to the ready method I have in my javaScript.

I've already tried with created and mounted but with no success.

My javascript:

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

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

My html:

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

Solution

  • Don't use vue.$data.{data} to access data immediately. use vue.{data}, and use refs to access dom in vue, here is a working example

    var vue = new Vue({
      el: '#main',
      data: {
        minRange: null,
        maxRange: null,
        slider: {
          startMin: 25,
          startMax: 75,
          min: 0,
          max: 100,
          start: 40,
          step: 1
        }        
      },
      methods: {
        updateSlider: function updateSlider() {
          this.$refs.slider.noUiSlider.set([this.minRange, this.maxRange]);
        }
      },
      mounted: function() {
        noUiSlider.create(this.$refs.slider, {
          start: [this.slider.startMin, this.slider.startMax],
          step: this.slider.step,
          range: {
            'min': this.slider.min,
            'max': this.slider.max
          }
        }); 
                
        this.$refs.slider.noUiSlider.on('update',(values, handle) => {
          this[handle ? 'maxRange' : 'minRange'] = parseInt(values[handle]);
        }); 
      }
    });
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/noUiSlider/11.0.3/nouislider.min.css">
    <script src="https://cdnjs.cloudflare.com/ajax/libs/noUiSlider/11.0.3/nouislider.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.5.13/dist/vue.min.js"></script>
    
    <div id="main">
      <br>
      <div id="slider" ref="slider"></div>
      <br>
      <input v-model="minRange" v-on:change="updateSlider" />
            
      <input v-model="maxRange" v-on:change="updateSlider" />
      </div>