For the sake of explanation, i made an example of code in a .vue
single file
<template>
<div id="app">
<h1>{{score}} : Score with undefined minScore but declared on data</h1>
<h1>{{score2}} : Score with undeclared/undefined minScore2</h1>
</div>
</template>
<script>
export default {
data() {
return {
minScore: undefined,
// Uncomment minScore2 to fix weird behavior
// minScore2: undefined
}
},
computed: {
score() {
return this.minScore 5
},
score2() {
return this.minScore2 5
}
},
created() {
setTimeout(() => {
this.minScore = 10
this.minScore2 = 10
}, 1000)
}
};
</script>
We use the above component to display score as a computed
property,
calculating it's value by summarizing it with the number 5.
After 1 second we try to update this.minScore
and this.minScore2
using the same setTimeout()
function.
The component loads, the template asks for the computed properties score
and score2
.
Both show NaN
at the beginning. After the 1 second passes, this.minScore
updates it's value correctly to the number 15, but this.minScore
stucks to the previous NaN
result.
The only difference is that minScore
is declared as undefined
explicitly and minScore2
is not.
There are not any error messages in console.
My question is why in Vue you need to implicitly initialize an undefined
property, when in javaScript both of the properties would be treated as undefined
?
P.S. I know that javaScript's outcome from the function `undefined number === NaN'
You can try it on the following codepen Link for Live Codepen
CodePudding user response:
You cannot add root-level reactive properties to an existing component instance: Docs.
You don't get any error, because the code is valid (you can console.log(this.minScore) and see that the property is set), but the properties that you add to this
are not reactive and the template update is not triggered.
If you need to not declare the properties upfront, there is a solution. First, make them non-root.
data(){
return {
unitializedProperties: {
// here will go new properties.
}
}
}
Then use the set() method to add new non-root reactive props.
this.$set(this.unitializedProperties, 'minScore', 10)
You can view it in action in your edited codepen