Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Vue.js @change and $event.target.value issue

I have this very basic HTML:

<div id="app">
  <input type="number" @change="start=$event.target.value">
  <input type="number" @change="final=$event.target.value">
  <button v-bind:disabled="isButtonActive">Proceed</button>
  {{start}} -- {{final}} -- {{res}}
</div>

And small vue.js code:

new Vue({
  el: '#app',
  data: {
      start: 0,
      final: 0
  },
  computed: {
      res() {
        return this.start < this.final;
      }
  },
  methods: {
    isButtonActive() {
      return this.start < this.final;
    }
  }
})

Now for the issue: If I put 2 to first input and 12 to second I got '2 -- 12' -- false, but why - 2 < 12?

If I put 12 to second input first and then 2 to the first I got

'2 -- 12 -- true'

If I change 2 to 45 I got '45 -- 12 -- true', oh

And now matter 'true' or 'false' button never becomes active. Please help. Here is the codepen link

like image 800
Paradoxetion Avatar asked Jan 28 '23 02:01

Paradoxetion


1 Answers

because the value of $event.target.value is one string, not number, you can convert string to number by parseInt. check below demo.

Vue.config.productionTip = false
new Vue({
  el: '#app',
  data: {
      start: 0,
      final: 0
  },
  computed: {
      res() {
        console.log(typeof this.start, typeof this.final, this.start < this.final)
        console.log('[Use ParseInt]', parseInt(this.start) < parseInt(this.final))
        return this.start < this.final;
      }
  },
  methods: {
    isButtonActive() {
      return this.start < this.final;
    }
  }
})
<script src="https://unpkg.com/[email protected]/dist/vue.js"></script>
<div id="app">
  <input type="number" @change="start=$event.target.value">
  <input type="number" @change="final=$event.target.value">
  <button v-bind:disabled="isButtonActive">Proceed</button>
  {{start}} -- {{final}} -- {{res}}
</div>

You can use the modifier= v-model.number then you should v-bind:disabled with the result(isButtonActive()) of the function instead of the function itself(isButtonActive), or use v-bind:disabled="res" will be better. (the difference between computed properties and methods is that computed properties are cached based on their dependencies), you can hit click me button to see the differences.

like below demo:

Vue.config.productionTip = false
new Vue({
  el: '#app',
  data: {
      start: 0,
      final: 0,
      testText: 'You will see isButtonActive is invoked, but computed properties will not'
  },
  computed: {
      res() {
        console.log('computed=res', typeof this.start, typeof this.final)
        return this.start < this.final;
      }
  },
  methods: {
    isButtonActive() {
      console.log('isButtonActive', typeof this.start, typeof this.final)
      return this.start < this.final;
    },
    test: function () {
      this.testText += '!'
    }
  }
})
<script src="https://unpkg.com/[email protected]/dist/vue.js"></script>
<div id="app">
  <input type="number" v-model.number="start">
  <input type="number" v-model.number="final">
  <button v-bind:disabled="isButtonActive()">Proceed</button>
  <button v-bind:disabled="res">Proceed</button>
  {{start}} -- {{final}} -- {{res}}
  <hr>
  <button @click="test()">Click me!!!</button>
  <p>{{testText}}</p>
</div>
like image 145
Sphinx Avatar answered Jan 31 '23 09:01

Sphinx