Vue parent component access to child component's computed Property

Ton*_*ush 5 vue.js vue-component vuejs2

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.

  1. Can you help me understand if I'm doing my computed and watch correctly?
  2. In the-parent component's watch, why does this.colors[i].IsSelected return undefined even though IsSelected renders just fine in the DOM?
<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>
Run Code Online (Sandbox Code Playgroud)
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
            }
        ]
    }
});
Run Code Online (Sandbox Code Playgroud)

Goo*_*ech 2

使用 $refs 直接访问子级。在 v-for ref 内部变成 and 数组。因为你的 v-for 是基于 this.color.length 无论如何使用相同的东西来循环 $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;
  }
}
Run Code Online (Sandbox Code Playgroud)