Search code examples
laravel-5.3vuejs2

Vue 2.0 Laravel 5.3 Parent Child relationship with slot


I have a project where when i click on a anchor on parent item-sorting-list a property of child item-card will change so it sort something out based on that property. However the data does not seem to pass to the child. I am wondering if there is anything wrong when i built up the parent child relationship in the meanwhile?

template (item-sorting-list)

 <a :name="subcat.name" href="" @click.prevent="getSelectedSubcat(subcat.name)">{{subcat.name}}</a>

methods (item-sorting-list)

methods: {

      getSelectedSubcat(subcat){
        var vm = this;
        vm.selectedSubcat = subcat
      }
    }

When I click on the subcat.name, it does actually store subcat.name into selectedSubcat (verified from Vue devtool) in the item-sorting-list component. The problem is item-card does not store it even though i put selectedSubcat as props

HTML (does this work as parent child relationship here?)

<item-sorting-list><item-card></item-card></item-sorting-list>

UPDATED item-card

export default {
    props:[
      'selectedSubcat'
    ],
    data(){
      return {
        products:[],
      }
    },
    mounted() {
      this.getAllProducts()
    },
    methods: {
      getAllProducts(){
        var vm = this;
        vm.$http.get('/getProducts').then((response)=>{
          vm.products = response.data.data.products;
        });
      }
    }
  }

from Vue devtool, item-card is included in the item-sorting-list, I would say that means they are parent child relationship? but then when i click something in item-sorting-list and change selectedSubcat, selectedSubcat in item-sorting-list does change but the selectedSubcat in item-card remains undefined. Sorry for my bad English.

UPDATE2

I notice that every example that I found online is that they set selectedSubcat in the new Vue with el="#app" in it instead of any other component (in my case item-sorting-list). Does that matter? I feel like the :selected-subcat="selectedSubcat in

<item-sorting-list>
   <item-card :selected-subcat="selectedSubcat"></item-card>
</item-sorting-list>

cannot read the selectedSubcat that I defined in the component item-sorting-list but instead if i set selectedSubcat in the following

const app = new Vue({
    el: '#app',
    data:{
      selectedSubcat:1
    }
});

it does read selectedSubcat as 1. So what I would say is that item-card does not consider item-sorting-list as its parent. But why and how can I make it to become item-card's parent? [NOTE: but in the Vue devtool the tree does show that item-sorting-list does consist of item-card, item-card does show after clicking the arrow on the left of item-sorting-list]


Solution

  • In VueJs, you have parent child relation, when you don't register a vue component globally, but you make a component available only in the scope of another instance/component by registering it with the components instance option, like following:

    var Child = {
      template: '<div>A custom component!</div>'
    }
    new Vue({
      // ...
      components: {
        // <my-component> will only be available in parent's template
        'my-component': Child
      }
    })
    

    In your case, I dont see selectedSubcat being passed as dynamic props to child component item-card. Dynamic props to data on the parent ensures whenever the data is updated in the parent, it will also flow down to the child:

    You probably have to pass it to child like following:

    <item-sorting-list>
       <item-card :selected-subcat="selectedSubcat"></item-card>
    </item-sorting-list>
    

    You also have to add props in your item-list like this:

    var itemList = {
      props: ["selectedSubcat"]
      template: '<div>Yout component!</div>'
    }
    

    notice I have converted it to kebab-case, because HTML being case-insensitive, camelCased prop names need to use their kebab-case (hyphen-delimited) equivalents(Documentation).