[Vuejs]-Why my vuejs wallpaper calculator doesn't work?

0👍

Your main problem is that you are using an input with type="text". The result of this is a string. When you start your application, the state of your component is initialised to what you set as data, which makes wall_length and wall_height numbers. The moment you change one of the inputs, the type of these variables changes to a `string.

Due to how javascript works, it will now do string concatenation instead of adding two numbers. It will then convert it back to a number for dividing by whatever this.selected is. The result is that instead of doing dividing 40 + 3 = 43 by this.selected, you are dividing “40” + 3 = 403 by this.selected. Notice the typeof checks I added behind the inputs to showcase this.

new Vue({
  el: "#app",
  data: {
    title: "Калькулятор шпалер",
    wall_length: 40,
    wall_height: 3,
    weight: [0.53, 1.05],
    rapport: 0,
    length: 10.05,
    selected: 0.53,
    polotno_for_room: 0,
    polotno_rulon: 0,
    result: 0
  },
  methods: {
    calc: function() {
      this.polotno_for_room = (this.wall_length + this.wall_height) / this.selected;
      this.polotno_rulon = this.length / (this.wall_height + 0.10);
      this.result = Math.ceil(this.polotno_for_room / this.polotno_rulon);
    }
  }

});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
  <h1>{{title}}</h1>
  <form v-on:submit.prevent>
    <span>Довжина стіни, м:</span><br>
    <input class="length" type="text" name="length" v-model.text.trim="wall_length"> {{ typeof wall_length }}<br>
    <span>Висота стіни, м:</span><br>
    <input class="heigth" type="text" name="heigth" v-model.text.trim="wall_height"> {{ typeof wall_height }}<br>
    <hr>
    <span>Ширина рулона, м:</span><br>
    <select v-model="selected">
      <option v-for="key in weight" :value="key">{{key}}</option>
    </select><br>
    <span>Довжина рулона, м:</span><br>
    <input class="length_roll" type="text" name="length_roll" v-model.text.trim="length" maxlength="5"><br>
    <span>Повтор малюнка (рапорт), см:</span><br>
    <input class="rapport" type="text" name="rapport" v-model.text.trim="rapport"><br><br>
    <input type="submit" value="Порахувати" v-on:click="calc">
  </form>
  <span>{{result}} рулонів шпалер</span>

</div>

One of your options is to use parseFloat(..) liberally. It will make sure you are using only numbers in your calculation.

new Vue({
  el: "#app",
  data: {
    title: "Калькулятор шпалер",
    wall_length: 40,
    wall_height: 3,
    weight: [0.53, 1.05],
    rapport: 0,
    length: 10.05,
    selected: 0.53,
    polotno_for_room: 0,
    polotno_rulon: 0,
    result: 0
  },
  methods: {
    calc: function() {
      this.polotno_for_room = (parseFloat(this.wall_length) + parseFloat(this.wall_height)) / parseFloat(this.selected);
      this.polotno_rulon = parseFloat(this.length) / (parseFloat(this.wall_height) + 0.10);
      this.result = Math.ceil(parseFloat(this.polotno_for_room) / parseFloat(this.polotno_rulon));
    }
  }

});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
  <h1>{{title}}</h1>
  <form v-on:submit.prevent>
    <span>Довжина стіни, м:</span><br>
    <input class="length" type="text" name="length" v-model.text.trim="wall_length"><br>
    <span>Висота стіни, м:</span><br>
    <input class="heigth" type="text" name="heigth" v-model.text.trim="wall_height"><br>
    <hr>
    <span>Ширина рулона, м:</span><br>
    <select v-model="selected">
      <option v-for="key in weight" :value="key">{{key}}</option>
    </select><br>
    <span>Довжина рулона, м:</span><br>
    <input class="length_roll" type="text" name="length_roll" v-model.text.trim="length" maxlength="5"><br>
    <span>Повтор малюнка (рапорт), см:</span><br>
    <input class="rapport" type="text" name="rapport" v-model.text.trim="rapport"><br><br>
    <input type="submit" value="Порахувати" v-on:click="calc">
  </form>
  <span>{{result}} рулонів шпалер</span>

</div>

Leave a comment