Search code examples
javascriptvuejs2computed-propertiesvue-reactivity

Computed prop in VueJS not updated until input lost focus


same as title says. A computed property from a object it´s not reactive until the input box lost the focus.

But if the object is in data, the value changes as soon as changed in the input.

I created a codepen with the example: https://codepen.io/Albvadi/pen/QWwMOQV

<div id="container">
  <div class="row justify-content-center">
    <div class="col-md-8">
      <div class="card">
        <div class="card-header">Match Component</div>

        <div class="card-body">
          <div class="container">
            <div class="row align-items-center">
              <div class="col-4 text-right">{{homeTeam.desc}}</div>
              <div class="col-2">
                <input class="form-control text-center" type="number" min="0" v-model.number="homeTeam.score" />
              </div>
              <div class="col-2">
                <input class="form-control text-center" type="number" min="0" v-model.number="awayTeam.score" />
              </div>
              <div class="col-4">{{ awayTeam.desc }}</div>
              <div class="row">
                <div class="col">
                  DATA:
                  <b>{{ homeTeam.score }}</b>
                </div>
                <div class="row">
                  <div class="col">
                    COMPUTED:
                    <b>{{ awayTeam.score }}</b>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</div>
new Vue({
  el: "#container",
  data: {
    homeTeam: {
      name: "SPA",
      desc: "Spain",
      score: 0
    }
  },
  computed: {
    awayTeam: function() {
      return {
        name: "GER",
        desc: "Germany",
        score: 0
      };
    },
  },
  mounted() {
    console.log("Component mounted.");
  }
});

If you change the first input, the data value is changed inmediate. If you change the second input, the computed value if changed only when input lost focus.

How can I solve this?

== EDIT ==

Thanks for your answers! I know that putting awayteam in the data section solves the problem, it was just an example to simplify my problem.

My problem was that along with the two results, I wanted to have a computed property to be able to issue to another component. I edited the codepen with the final result: https://codepen.io/Albvadi/pen/jOELYwN and it´s working correctly.

But @Sami Kuhmonen comments that computed properties are only read properties but in my checkFinalResult I´m setting the computedMatch.. It´s the right approach??


Solution

  • Computed properties should be considered read only. Every time there's a change in the properties they reference their value is computed from other values and all changes are lost (or at least should be thought that way, there may be cases where some values remain). Even though sometimes changing their properties seems to work it's not guaranteed and they may change whenever.

    In the codepen you already have the computed property referencing other properties from the object, so you'll have to add all the things you want to change similarly and then change that value. This will cause the computed value to be re-evaluated and the changes will be visible and persisted.

    Note that building a computed object from a lot of separate things might not be the most performant way and it depends on the situation how it should be handled. If the values are only used within the component then it's easy to just use them directly but if you need an object of specific form for something and need it reactive then computed property might be the way to go.