1
votes

I have a component which receives a list of items. Each one of those items will be a child component inside the main one. Each child component has a slot where I need to distribute content.

How do I distribute the content (the name) of each item to the correct slot?

The root app:

<div id="app">
  <test-list :items="items"></test-list>
</div>

var app = new Vue({
  el: "#app",
  data: {
    items: [
        {id: 1, name: "item 1"},
        {id: 2, name: "item 2"},
        {id: 3, name: "item 3"},
        {id: 4, name: "item 4"},
        {id: 5, name: "item 5"},
    ]
  }
});

Main component:

Vue.component('test-list', {
  template: '#test-list',
  props: {
    items: []
  },
});

<script id='test-list' type='x-template'>
  <ul class="list-group">
    <test-item v-for="item in items" :id="item.id" :name="item.name"></test-item>
  </ul>
</script>

Child component:

Vue.component('test-item', {
  template: '#test-item',
  props: {
    id: 0,
    name: ""
  }
});

<script id='test-item' type='x-template'>
  <li class="list-group-item">
    <slot>default text {{name}}</slot>
  </li>
</script>

The best I was able to do was to distribute the same content over all the items: JSFiddle here

Any ideas? Thanks!

1

1 Answers

1
votes

If I'm getting it right, this is what you want. You have to use named slots, in this way:

root app

<test-list :items="items">    
</test-list>

Main component

<ul class="list-group">
    <test-item v-for="item in items" :id="item.id" :name="item.name">
        <span :slot="item.name"></span>
    </test-item>
  </ul>

Child component

<li class="list-group-item">
    <slot :name="name">default text {{name}}</slot>
  </li>

Things to note:

  1. The slot component is included in the child, with a name attribute
  2. The element that is going in the slot is placed in the parent with a slot attribute.
  3. Both attribute have a v-on directive (I used the : shorthand), so you can bind the content of your Vue instance

Hope it helps.