Blog>
Snippets

Using Named Slots with v-for

Provides an example of rendering a list of items where each item uses a named slot within a child component.
<template>
  <div id="app">
    <my-list :items="groceryList">
      <template v-slot:item="{ item }">
        <!-- this is the named slot where we'll pass our scoped item -->
        <li>{{ item.name }} - ${{ item.price }}</li>
      </template>
    </my-list>
  </div>
</template>
This is the HTML template code where a custom component <my-list> is used. The component takes a prop 'items' which is an array of objects. The v-for is used within the named slot 'item' to render each item of the list.
<script>
Vue.component('my-list', {
  props: ['items'],
  template: `
    <ul>
      <slot name="item" v-for="item in items" :item="item"></slot>
    </ul>
  `,
});

new Vue({
  el: '#app',
  data: {
    groceryList: [
      { id: 0, name: 'Vegetables', price: 10 },
      { id: 1, name: 'Cheese', price: 7 },
      { id: 2, name: 'Bread', price: 5 }
    ]
  }
});
</script>
This is the JavaScript code where the Vue component <my-list> is defined. It accepts a prop 'items', which is expected to be an array. Within the component's template, a named slot 'item' is provided with a v-for directive to iterate over the 'items' prop. Also, the root Vue instance is created, attaching to the element with id 'app' and defining the data model including the grocery list.
<style>
  #app { font-family: Arial, sans-serif; }

  ul { list-style: none; padding: 0; }
  li { margin: 5px 0; }
</style>
This is the CSS that styles the Vue application. It sets the font family for the #app container and removes list styling while adding some margins to each 'li' element.