在输入失去焦点之前,VueJS中的计算道具不会更新

时间:2019-12-28 17:09:25

标签: javascript vuejs2 computed-properties vue-reactivity

与标题相同。通过对象计算得到的属性,直到输入框失去焦点后,该对象才会反应。

但是如果对象位于数据中,则输入中的值将立即更改。

我创建了一个带有以下示例的codepen: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.");
  }
});

如果更改第一个输入,则数据值将立即更改。 如果更改第二个输入,则仅当输入失去焦点时才更改计算值。

我该如何解决?

==编辑==

感谢您的回答! 我知道在数据部分中加入团队可以解决问题,这只是简化我的问题的一个示例。

我的问题是,除了这两个结果之外,我还希望有一个可计算的属性才能发布给另一个组件。 我用最终结果https://codepen.io/Albvadi/pen/jOELYwN编辑了代码笔,它工作正常。

但是@Sami Kuhmonen评论说,计算属性只是读取属性,但是在我的checkFinalResult中,我设置了computedMatch。 这是正确的方法?

3 个答案:

答案 0 :(得分:2)

在您的情况下,为什么此计算属性不会立即更新DOM元素,因为它没有data实例的Vue引用。这里,它返回一些static仅值,这不是computed属性的目的。当您需要根据自己的computed property实例中的data property计算或做出某些决定时,vue就变成了现实。

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>

答案 1 :(得分:2)

计算的属性应被视为只读。每当它们引用的属性发生变化时,它们的值都是从其他值计算得出的,并且所有更改都将丢失(或者至少应该以这种方式认为,可能会保留某些值)。即使有时更改其属性似乎可行,也无法保证,并且随时可能更改。

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

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

答案 2 :(得分: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.");
   }
 });