2

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??

4

3 回答 3

2

在您的情况下,为什么这个计算属性不会DOM立即更新元素,因为它没有dataVue实例的引用。在这里,它只返回一些static值,这不是computed属性的目的。computed property当您需要根据您data propertyvue实例计算或计算某些决定时,就可以达到目的。

new Vue({
  el: "#container",
  data: {
    homeTeam: {
      name: "SPA",
      desc: "Spain",
      score: 0
    },
    awayTeam: {
      name: "GER",
      desc: "Spain",
      score: 0
    },
  },
  mounted() {
    console.log("Component mounted.");
  }
});
<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>

<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>

于 2019-12-28T17:20:54.133 回答
2

计算属性应该被认为是只读的。每次它们引用的属性发生变化时,它们的值都是从其他值计算出来的,并且所有更改都会丢失(或者至少应该这样认为,可能存在一些值保留的情况)。即使有时更改它们的属性似乎有效,但也不能保证,它们可能随时更改。

在 codepen 中,您已经拥有引用对象中其他属性的计算属性,因此您必须类似地添加所有要更改的内容,然后更改该值。这将导致计算值被重新评估,并且更改将可见并保持不变。

请注意,从许多单独的事物构建计算对象可能不是最高效的方式,它取决于应如何处理它的情况。如果这些值仅在组件中使用,那么直接使用它们很容易,但是如果您需要特定形式的对象并需要它的反应性,那么计算属性可能是要走的路。

于 2019-12-29T12:58:57.053 回答
1

为什么要为这个任务使用计算属性?我会这样做。

  new Vue({
     el: "#container",
     data: {
        homeTeam: {
        name: "SPA",
       desc: "Spain",
       score: 0
     },
    awayTeam:  {
       name: "GER",
       desc: "Germany",
       score: 0
     },
   },
   mounted() {
      console.log("Component mounted.");
   }
 });
于 2019-12-28T17:21:42.337 回答