Reputation:
I understand that when a property/data being watched is changed/re-assigned, then the watch method for that property/data is triggered.
However, in this code snippet, the watch method for initTasks is triggered although initTasks is not changed/touched (or so it seems).
This code snippet is supposed to increment the "estimate" every time a task is added. However, estimate is not incremented because estimate is overridden by initTask's watch method every time.
https://jsfiddle.net/akosipax/1qtLfyn4/43/
Vue.component('customcomponent', {
props: ['initTasks', 'initEstimate'],
data() {
return {
tasks: [],
estimate: 0,
}
},
template: `
<div>
<ul>
<li v-for="(task, index) in tasks" :key="index">
{{task.text}}
</li>
</ul>
<p>It will take you {{estimate}} hours to do all of these!</p>
<button @click="addTask">Add task</button>
</div>
`,
methods: {
initialize() {
this.tasks = this.initTasks;
this.estimate = this.initEstimate;
},
addTask() {
Vue.set(this.tasks, this.tasks.length, {
text: "Do this new task"
});
this.estimate++;
}
},
watch: {
initTasks: function(oldval, newval) {
console.log('watch for initTasks triggered!');
this.initialize();
}
},
mounted() {
console.log('mounted() triggered!')
this.initialize();
},
created() {
console.log('created() triggered!')
},
updated() {
console.log('updated() triggered!')
},
destroyed() {
console.log('updated() triggered!')
}
});
new Vue({
el: "#app",
data: {
tasks: [
{ text: "Learn JavaScript"},
{ text: "Learn Vue"},
{ text: "Play around in JSFiddle"},
{ text: "Build something awesome"}
],
estimate: 5
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<customcomponent :init-tasks="tasks" :init-estimate="estimate"></customcomponent>
</div>
Upvotes: 0
Views: 206
Reputation: 27729
If you change your initialize method to:
initialize() {
this.tasks = this.initTasks.slice();
this.estimate = this.initEstimate;
}
Everything will work. I think the watcher is being triggered because when you change the tasks array the initTasks is also changed because arrays are Mutable.
If you are using es2015 and beyond you can do:
this.tasks = ...[this.initTasks];
OR
this.tasks = Array.from(this.initTasks);
Upvotes: 1