<div class="flex items-center justify-center w-full mb-6">
<div id="app">
<div class="flex justify-center">
<button
v-for="(breed, i) in breeds"
:key="i"
class="hover:bg-blue-500 text-sm py-1 px-2 border border-blue-500 rounded m-2"
:class="{
'text-blue-500 hover:text-white': breed.key !== breedKey,
'bg-blue-500 text-white': breed.key === breedKey
}"
@click="currentBreed = i"
>
{{ breed.name }}
</button>
</div>
<div class="rounded shadow-md bg-gray-100 mt-4">
<async :url="`https://dog.ceo/api/breed/${breedKey}/images`">
<template v-slot:default="{ pending, error, data }">
<div v-if="pending" class="text-center">
<img src="https://files.codethink.de/public/Preloader_2.gif" alt="loading" class="mx-auto">
<span class="text-gray-400 font-medium">Loading ...</span>
</div>
<div v-else-if="error" class="bg-orange-100 border-l-4 border-orange-500 text-orange-700 p-4" role="alert">
{{ error }}
</div>
<ul v-else class="flex flex-wrap justify-between">
<li v-for="(image, i) in data.message.slice(0,24)" :key="i" class="m-2">
<img :src="image" class="rounded h-24" />
</li>
</ul>
</template>
</async>
</div>
</div>
</div>
<div class="bg-gray-400 text-gray-600 px-4 py-3 rounded relative text-sm text-center"><a href="https://twitter.com/_lhermann" class="text-blue-600 hover:underline">Follow me on Twitter</a></div>
const Async = Vue.component('async', {
props: {
url: { type: String, default: "", required: true },
params: { type: Object, default: () => ({}) }
},
data() {
return {
pending: true,
error: false,
data: null
};
},
watch: {
url() {
this.requestData();
},
params: {
handler() {
this.requestData();
},
deep: true
}
},
mounted() {
this.requestData();
},
methods: {
async requestData() {
this.pending = true;
try {
const { data } = await axios.get(this.url, { params: this.params });
this.data = data;
this.error = false;
} catch (e) {
this.data = null;
this.error = e;
}
this.pending = false;
}
},
render() {
return this.$scopedSlots.default({
pending: this.pending,
error: this.error,
data: this.data
});
}
});
new Vue({
el: '#app',
components: { Async },
data() {
return {
currentBreed: 0,
breeds: [
{ name: "Golden Retriever", key: "retriever/golden" },
{ name: "German Shepherd", key: "germanshepherd" },
{ name: "Husky", key: "husky" },
{ name: "Pug", key: "pug" },
{ name: "(Error)", key: "error" },
]
}
},
computed: {
breedKey() {
return this.breeds[this.currentBreed].key;
}
}
})