在输入失去焦点之前,VueJS 中的计算道具不会更新
Posted
技术标签:
【中文标题】在输入失去焦点之前,VueJS 中的计算道具不会更新【英文标题】:Computed prop in VueJS not updated until input lost focus 【发布时间】:2020-04-18 03:39:12 【问题描述】:和标题一样。对象的计算属性在输入框失去焦点之前不会反应。
但如果对象在数据中,则值在输入中更改后立即更改。
我用示例创建了一个代码笔: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.");
);
如果您更改第一个输入,则数据值会立即更改。 如果更改第二个输入,则计算值仅在输入失去焦点时才更改。
我该如何解决这个问题?
== 编辑 ==
感谢您的回答! 我知道将team放在数据部分可以解决问题,这只是简化我的问题的一个例子。
我的问题是,除了这两个结果之外,我还希望有一个计算属性能够发布到另一个组件。 我用最终结果编辑了 codepen:https://codepen.io/Albvadi/pen/jOELYwN,它工作正常。
但是@Sami Kuhmonen cmets 计算的属性只是读取属性,但在我的checkFinalResult
中,我正在设置computedMatch
..
这是正确的方法吗??
【问题讨论】:
不应更改计算值。它们是根据其他数据计算的,因此是只读的。 谢谢!你能检查我的编辑吗? 你永远不会在计算属性中设置任何东西。这是正确的做法。所以你仍然在做错事。如果您确实需要修改计算数据,那么其中的每个字段都引用data
中的字段,然后您可以根据需要进行修改。就像你已经对其中一些做的那样。
再次感谢您。如果您愿意,请将您的评论作为答案发布,我会检查它是否为正确答案。我认为这是对我的问题最有帮助的评论...我会尝试重构我的数据以不在计算属性中设置任何内容...再次感谢!
【参考方案1】:
计算属性应被视为只读。每次他们引用的属性发生变化时,它们的值都是从其他值计算出来的,并且所有变化都会丢失(或者至少应该这样认为,可能存在一些值保留的情况)。尽管有时更改它们的属性似乎有效,但这并不能保证,它们可能随时更改。
在 codepen 中,您已经拥有引用对象中其他属性的计算属性,因此您必须添加所有您想要更改的类似内容,然后更改该值。这将导致计算值被重新评估,并且更改将可见并持久化。
请注意,从许多单独的事物中构建计算对象可能不是最高效的方式,它取决于应如何处理它的情况。如果这些值仅在组件中使用,那么直接使用它们很容易,但是如果您需要特定形式的对象并需要它的反应性,那么计算属性可能是要走的路。
【讨论】:
【参考方案2】:在你的情况下,为什么这个计算属性不会立即更新 DOM
元素,因为它没有 data
引用 Vue
实例。在这里,它只返回一些 static
值,这不是 @ 987654325@物业的用途。当您需要根据您的data property
的vue
实例来计算或计算某些决策时,computed property
就派上用场了。
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>
【讨论】:
【参考方案3】:为什么你在这个任务中使用计算属性?我会这样做。
new Vue(
el: "#container",
data:
homeTeam:
name: "SPA",
desc: "Spain",
score: 0
,
awayTeam:
name: "GER",
desc: "Germany",
score: 0
,
,
mounted()
console.log("Component mounted.");
);
【讨论】:
谢谢!您可以检查编辑以推荐最佳方法吗?以上是关于在输入失去焦点之前,VueJS 中的计算道具不会更新的主要内容,如果未能解决你的问题,请参考以下文章