[Vuejs]-Vue dynamic calculation on input change

2👍

Use a computed property:

Vue.config.devtools = false;
Vue.config.productionTip = false;
new Vue({
  el: '#app',
  data: () => ({
    s: 0,
    e: 0
  }),
  computed: {
    tot() {
      return Number(this.s) + Number(this.e);
    }
  },
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
  <input v-model="s" type="number">
  <input v-model="e" type="number">
  <pre>{{s}} + {{e}} = {{tot}}</pre>
</div>

Also note you need to cast your values as Number() if you want the sum to be correct. If they’re interpreted as strings a + b = ab.

👤tao

1👍

Very close to tao answer. Only "fix" two User experience issues (Not directly related to Vue).

Issue 1: "030" or "30" ahhhh:

First, if you set a default value (0 for example), when the user focuses input and type "3" the output is 03! (or 30) ==> Very annoying (Especially on mobile).

enter image description here

Sometimes it’s better to set the input value to null and show input placeholder (Fix this annoying issue).

Issue 2 (No meaning result):

The output 0 + 0 = 0 does not contribute too much to the user. Sometimes it’s better to put the sum inside v-if.
enter image description here

<p v-if="number1 && number2">{{total}}</p>

Basic code example

Vue.config.devtools = false;
Vue.config.productionTip = false;
new Vue({
  el: '#app',
  data: () => ({
    number1: {
      type: Number,
      value: null,
      placeholder: "Enter number 1",

    },
    number2: {
      type: Number,
      value: null,
      placeholder: "Enter number 2",

    }
  }),
  computed: {
    total() {
      return Number(this.number1.value) + Number(this.number2.value);
    }
  },
})
span{
  color: red;
  font-weight: bold
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
  <h3></h3>
  <div>
    <label>Number 1:</label>
    <input autofocus v-model="number1.value" type="number" v-bind:placeholder="number1.placeholder">
  </div>
  <div>
    <label>Number 2:</label>
    <input v-model="number2.value" type="number" v-bind:placeholder="number2.placeholder">
  </div>
  <p>Total:<span v-if="number1.value && number2.value"> {{total}}</span></p>
</div>

v-model.lazy also sometimes useful for calucations:

By default, v-model syncs the input with the data after each input
event (with the exception of IME composition, as stated above). You
can add the lazy modifier to instead sync after change events. https://v2.vuejs.org/v2/guide/forms.html#lazy

Leave a comment