Scoped slot in List Component

Scoped slot Component demo by http://qcode.in

by Saqueib Ansari

HTML

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.6/css/bootstrap.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.4.2/vue.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.16.2/axios.min.js"></script>
<!-- Templates -->
<template id="list">
  <div class="panel panel-default" :class="panelClass">
  
    <!-- title named slot -->
    <div class="panel-heading">
      {{ title }} 
      <span v-if="loading" class="pull-right text-danger">
        Loading...
      </span>
    </div>
      
    <!-- defult slot for body -->
    <ul class="list-group">
      <li v-for="item in result" class="list-group-item">
        <!-- scope slot passed item -->
        <slot :item="item">
          {{ item.first_name + ' ' + item.last_name }}
        </slot>          
      </li>
    </ul>
         
  </div>
</template>

<div class="container">
  <div id="app">
    <div class="row">
      <div class="col-md-12 text-center">
        <h4>VueJS Scoped slot demo 
            <br>
            <small>One component, four variations</small>             </h4>
      </div>
    </div>
    
    <div class="row">
      <div class="col-xs-6">
      
        <q-list 
          title="Users List" 
          url="https://reqres.in/api/users?per_page=10">
        </q-list>
        <!-- Default slot template -->
        
        <q-list 
          title="Photo List"
          url="https://jsonplaceholder.typicode.com/photos?_page=4"
          >
          <!-- custom template -->
          <template scope="props">
                <img 
                  :src="props.item.url" alt=""
                  class="img-responsive"
                  >
                <h4>{{ props.item.title }}</h4>
          </template>
        </q-list>
        <!-- Custom scoped slot template -->
        
      </div>
      
      <div class="col-xs-6">
      
        <q-list 
          title="Users with Avatar List" 
         ...

CSS

body {
  margin-top: 1rem
}

JavaScript

// Component 
Vue.component('q-list', {
  template: '#list',
  props: ['panelClass', 'title',  'url'],
  data: function() {
  	return {
    	result: [],
      loading: false
    }
  },
  created: function() {
  	// check for a url
    if( ! this.url ) throw new Error('Need a url for JSON API to fetch the list.');
    
    // load the data
    let vm = this;
    vm.loading = true;

    axios.get(this.url).then(function(res) {
      vm.result = res.data.data || res.data;
      vm.loading = false;
      console.log('data loaded');
    })
    
  }
});

// Initialize Vue
new Vue({
  el: '#app'
})