I have a data variable named monRaw
that is a Moment
object representing the first day of current week:
...
data() {
return {
monRaw: moment().startOf('isoWeek')
}
},
...
Then I have a computed property named weekTitle
that displays it along with some text (it does more than that in my project, but I simplified it here):
...
computed: {
weekTitle: function() {
alert('updating computed property...');
return `Current week starting on ${this.monRaw.format('DD')}`;
}
},
...
Finally, a method named viewNextWeek()
changes my data variable to the following week's first day:
...
methods: {
viewNextWeek: function() {
this.monRaw = this.monRaw.add(1, 'weeks');
},
...
In my template, I display my computed property along with a button triggering my method:
{{ weekTitle }}
<button @click="viewNextWeek">Next Week</button>
For some reason though, my computed property does NOT get updated when I change the data variable it's based on.
It doesn't even try to: my alert()
gets triggered on page load only, not any more after that when clicking the button.
What's wrong here?
Moment.add
mutates the moment variable, so you are just assigning the same object back to itself, which results in no change.
Per the docs:
If you want to create a copy and manipulate it, you should use moment#clone before manipulating the moment.
new Vue({
el: '#app',
data: {
monRaw: moment().startOf('isoWeek')
},
computed: {
weekTitle: function() {
alert('updating computed property...');
return `Current week starting on ${this.monRaw.format('DD')}`;
}
},
methods: {
viewNextWeek: function() {
const newValue = this.monRaw.clone().add(1, 'weeks');
this.monRaw = newValue;
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.22.2/moment.min.js"></script>
<script src="https://unpkg.com/vue@latest/dist/vue.js"></script>
<div id="app">
{{ weekTitle }}
<button @click="viewNextWeek">Next Week</button>
</div>