Reputation: 227
With the code below, if you click the add you can see in the console that the value changes, but the view is not updated.
new Vue({
el: '#app',
data: {
dateValue: new Date(2017,0,1),
},
methods: {
addOne: function () {
this.dateValue.setDate(this.dateValue.getDate() + 1);
console.log('new date',this.dateValue);
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.13/vue.js"></script>
<div id="app">
Date Value : {{ dateValue }}<br />
<button v-on:click="addOne">Add One</button> <br />
</div>
If I introduce simple integer value and display it next to the date, it will work properly and it causes the date value to update properly as well.
new Vue({
el: '#app',
data: {
dateValue: new Date(2017,0,1),
intValue: 0
},
methods: {
addOne: function () {
this.dateValue.setDate(this.dateValue.getDate() + 1);
this.intValue++;
console.log('new date',this.dateValue);
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.13/vue.js"></script>
<div id="app">
Date Value : {{ dateValue }} Int Value : {{ intValue }}<br />
<button v-on:click="addOne">Add One</button> <br />
</div>
I have fussed with setting the date in various ways and I just don't understand what is going on here. Somehow the mutation of the date isn't being detected. I am hopeful that someone can shed some light on this.
Upvotes: 3
Views: 2712
Reputation: 106365
This line...
this.dateValue.setDate(this.dateValue.getDate() + 1);
... changes the 'contents' of a Date object stored in this.dateValue
, but not the object (the reference) itself. Essentially, this.dateValue
has the same value as before, so no change is detected by the corresponding mechanism, and no view update is triggered. Now compare with this snippet:
new Vue({
el: '#app',
data: {
dateValue: new Date(2017,0,1),
},
methods: {
addOne: function () {
this.dateValue = new Date(
this.dateValue.setDate(this.dateValue.getDate() + 1)
);
console.log('new date',this.dateValue);
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.13/vue.js"></script>
<div id="app">
Date Value : {{ dateValue }}<br />
<button v-on:click="addOne">Add One</button> <br />
</div>
As new Date object is created at each call of addOne()
, the change is detected, and the corresponding view is updated.
Why does your second snippet work, you might ask? Again, the answer is about change detection. As intValue
value is changed, it's enough to trigger re-render of the whole component (app instance, in this particular case).
And yes, while building a new Virtual DOM for the changed state, VueJS retrieves values of all the properties - not just the changed ones. It's the difference between new and old V-DOMs that will be applied to the real DOM.
Upvotes: 8