简体   繁体   中英

How to handle multiple array filters with Vue JS?

Not sure when to use computed properties vs watch to display my data. I'm building an app with the PokeAPI, and I want to toggle between Type and Generation to display the pokemon. So far I have a JS file that stores all the pokemon in an array:

//pokeData.js
import axios from 'axios'

const allPokes = [];

export default{
    getPokemon(){
        if(allPokes.length === 0){
            for(let i=1; i<=809; i++){
                axios.get(`https://pokeapi.co/api/v2/pokemon/${i}`)
                .then(response => {
                    allPokes.push(response.data);
                    allPokes.sort((a, b) => a.id - b.id);
                });
            }
        }
        return allPokes
    }
}

I don't want to repeatedly call 809 Objects from an API, so I call them in the mounted() in my Vue, and want to filter them from there:

//Container.vue
//takes two props, 'currentType' and 'currentGen', to use to filter the pokemon

<template>
        <div 
        v-for="(pokemon, index) in allPokemon"
        :key="index">
            <h2>{{ pokemon.name }}</h2>
        </div>
</template>

<script>
import Pokemon from '../pokeData'

export default {
    props: ['currentType', 'currentGen'],
    data(){
        return{
            allPokemon: [],
        }
    },
    mounted(){
            this.allPokemon = Pokemon.getPokemon();
    },
    watch: {
        currentType: function(newType){
            const typePokes = this.allPokemon.filter(pokemon => {
                    if(pokemon.types[0].type.name == newType){
                        return true
                     }
                  this.allPokemon = typePokes  
            });

I know this is wrong, but I don't know how to fix it. I know you can use List Rendering as suggested in the official documents, but it doesn't say how to use it for multiple filters. https://v2.vuejs.org/v2/guide/list.html#Replacing-an-Array

Any advice is welcome: how to better cache the initial API call; to use watch or computed...

A computed prop is what you need in this situation:

computed: {
  filteredPokemons () {
    if (this.currentType) {
      return this.allPokemon.filter(pokemon => pokemon.types[0].type.name == this.currentType)
    }
    if (this.currentGen) {
      // I assumed that a prop is named 'gen', just replace with an actual prop
      return this.allPokemon.filter(pokemon => pokemon.types[0].gen.name == this.currentGen)
    }
    // you didn't mentioned what to show when both currentType and currentGen is empty
    // I assumed it should be an empty array
    return []
  }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM