haakym
haakym

Reputation: 12368

How to access child component data in v-if outside of component?

In short, I want to get a value from a child component and check what it is in the parent. I have a working implementation using computed properties and a reference via v-ref on the child component, but I was wondering if I am doing it the right way and if there's a better/proper way to do it.

To get to specifics, I have a component with checkboxes, the checked checkboxes' values within this component are kept in the components data in an array variable named selected. Outside of the component I want to conditionally show a <div> using v-if however I'm unsure how to correctly grab the child component's selected value.

Here's a brief overview of my code:

component mark up

<student-table
    v-ref:student-table
    :data="students"
    :course="course"
    :columns="columns"
>
</student-table>

component registration

Vue.component('student-table', {

    /* unrelated code */

    data: function () {
        return {
            selected: []
        }
    },

    /* unrelated code */
})

main vue instance

var vueApp = new Vue({
    /* unrelated code */

    computed: {
        selected: function () {
            return this.$refs.studentTable.selected.length
        }
    },

    /* unrelated code */
})

Then in my html I can reference selected and I'll get the length of StudentTable.selected and thus be able to use it in my v-if

Thanks for any guidance or help!

Edit

I'm getting this in my console:

[Vue warn]: Error when evaluating expression "function () {
    return this.$refs.studentTable.selected.length
}". Turn on debug mode to see stack trace.

Upvotes: 0

Views: 915

Answers (2)

haakym
haakym

Reputation: 12368

This is how I now have it working, I'm not sure this is the best way but I'm not getting any console.warn alerts in my console. Would love any feedback. Many thanks to @Douglas.Sesar

// child
Vue.component('student-table', {

    parent: vueApp,

    data: function () {
        return {
            selected: []
        }
    },

    watch: {
        selected: function() {
            this.$dispatch('updateSelected', this.selected);
        }
    },

})

// parent
var vueApp = new Vue({

    components: {
        child: studentTable
    },

    data: {
        selected: []
    },

    events: {
        updateSelected: function(selected) {
            this.selected = selected;
        }
    },

})

Upvotes: 0

Douglas.Sesar
Douglas.Sesar

Reputation: 4430

There are several ways to share data between parents / components such as 2-way binding between parent/child and also sending and listening for events.

Here is an events example with $broadcast and $dispatch:

parent vue:

var parentVue = new Vue({
     ...
     compiled: function(){
          this.$on('receiveDataFromChild', function(){
               //do something with the data from the child
          });
     },
     methods: {
          checkChildForData: function(){
               this.$broadcast('pleaseSendDataToYourMama');
          }
     }
}); 

child vue:

var childVue = new Vue({
     ...
     compiled: function(){
          this.$on('pleaseSendDataToYourMama', function(){
               this.$dispatch('receiveDataFromChild',this.someImportantData);
          });
     }
}); 

Upvotes: 2

Related Questions