Vue Pokemons!
Features: API fetching, array filtering, recursive component
by tlopasha
HTML
<div id="vue">
<div>
<h2>
Types
</h2>
<ul>
<li @click="selected = undefined" :class="{clickable:true, current:!selected}">All</li>
<li v-for="type in types" @click="selected = type" :class="{clickable:true, current:type == selected}">{{type}}</li>
</ul>
</div>
<div>
<h2>
Pokemon
</h2>
<ul>
<li v-for="pokemon in filtered" @click="showPokemon = pokemon" :class="{clickable:true,current:pokemon == showPokemon}">
{{pokemon.Name}}
<div class="types">{{pokemon.Types && pokemon.Types.join(' ')}}</div>
</li>
</ul>
</div>
<div v-if="showPokemon">
<h2>{{showPokemon.Name}}</h2>
<img :src="'https://github.com/PokeAPI/sprites/raw/master/sprites/pokemon/' + Number(showPokemon.Number) + '.png'">
<json :data="showPokemon"></json>
</div>
</div>
CSS
body{
margin:0
}
#vue{
display:flex;
font-family:sans-serif;
}
#vue > div{
width:33%;
padding:5px;
display:flex;
flex-direction:column;
box-sizing:border-box;
max-height:100vh;
}
ul{
list-style:none;
padding:0;
box-shadow:0px 1px 5px #aaa;
background:white;
overflow:auto;
}
li{
padding:10px;
display:flex;
flex-wrap:wrap;
}
li:nth-child(even){
background:#f8f8f8;
}
.clickable:hover{
cursor:pointer;
background:#cfc;
}
li.current, .clickable.current{
background:#afa;
}
li > ul{
width:100%
}
b{
margin-right:auto;
}
b ~ ul{
margin-top:5px;
}
img{
display:block;
height:96px;
margin:0 auto;
transform:scale(2);
image-rendering:pixelated;
}
.types{
font-size:12px;
color:grey;
margin-left:auto;
}
JavaScript
new Vue({
el: '#vue',
data() {
return {
selected: undefined,
pokemons: [],
types: [],
showPokemon:undefined
}
},
created(){
fetch('https://raw.githubusercontent.com/BrunnerLivio/PokemonDataGraber/master/output.json')
.then(res => res.json()).then(pokemons => {
this.pokemons = pokemons.filter(pokemon => pokemon.Name)
for(var pokemon of this.pokemons){
for(var type of pokemon.Types){
if(!this.types.includes(type)){
this.types.push(type)
}
}
this.types = this.types.sort()
}
})
},
computed: {
filtered() {
return this.selected ? this.pokemons.filter(pokemon => pokemon.Types && pokemon.Types.includes(this.selected)) : this.pokemons
}
},
components:{
json:{
name:'json',
props:['data'],
template:
`<ul v-if="typeof data == 'object'">
<li v-for="item, key in data">
<b v-if="!Array.isArray(data)">{{key}}</b>
<json :data="item"></json>
</li>
</ul>
<span v-else>{{data}}</span>
`
}
}
})