In Vue JS, I'm unable to watch for changes to an array when changes are made within an array element's (child's) computed Property.
I've boiled down the issue in a sample JSFiddle I wrote, so the example may not make sense logically but it does show my issue.
https://jsfiddle.net/trush44/9dvL0jrw/latest/
I have a parent component that holds an array of colors. Each color is rendered using a child component. The child component has a computed Property called 'IsSelected'. When the 'IsSelected' computed Property changes on any array element, I need to loop through the entire array to see if at least 1 element in the array is still selected then set IsAnyCheckboxChecked accordingly.
<div id="app">
Is any Color Selected?...... {{IsAnyCheckboxChecked}}
<the-parent inline-template :colors="ColorList">
<div>
<the-child inline-template :color="element" :key="index" v-for="(element, index) in colors">
<div>
{{color.Text}}
<input type="checkbox" v-model="color.Answer" />
IsChecked?......{{IsSelected}}
</div>
</the-child>
</div>
</the-parent>
</div>
Vue.component('the-child', {
props: ['color'],
computed: {
IsSelected: function () {
return this.color.Answer;
}
}
});
Vue.component('the-parent', {
props: ['colors'],
watch: {
colors: {
handler: function (colors) {
var isAnyCheckboxChecked = false;
for (var i in this.colors) {
// IsSelected is undefined even though it's a 'computed' Property in the-grandchild component
if (this.colors[i].IsSelected) {
isAnyCheckboxChecked = true;
break;
}
}
this.$parent.IsAnyCheckboxChecked = isAnyCheckboxChecked;
},
deep: true
}
}
});
// the root view model
var app = new Vue({
el: '#app',
data: {
'IsAnyCheckboxChecked': false,
'ColorList': [
{
'Text': 'Red',
'Answer': true
},
{
'Text': 'Blue',
'Answer': false
},
{
'Text': 'Green',
'Answer': false
}
]
}
});
use $refs for accessing the child directly. Inside a v-for ref becomes and array. since your v-for is based on this.color.length anyway use the same thing to loop though the value in the $ref var.
https://jsfiddle.net/goofballtech/a6Lu4750/19/
<the-child ref="childThing" inline-template :color="element" :key="index" v-for="(element, index) in colors">
for (var i in this.colors) {
if (this.$refs.childThing[i].IsSelected) {
isAnyCheckboxChecked = true;
break;
}
}