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'
})