简体   繁体   中英

I've created multiple filters functions and each one does its own job right, however, I'm not sure how to chain them so they all work together

I'm trying to create filtering functionality which would allow me to filter cards from a collectible card game based on several criteria. I've already created 6 functions which filter based on a single criteria like card name, card cost or card rarity. These functions work fine and do their job, however, right now I can only use one of them at a time.

What I am trying to do is combine or chain these functions so that they are all taken into account before returning the final array with cards. I'm wondering if there's any easy way to do that?

Right now I have this:

<template>
    <div class="cards">
        <div class="cards-list">
            <div class="card" v-for='card in filteredByCost' @click='specificCard(card.cardCode)'>
                <div class="card-image">
                    <img class='responsive-image' :src='"../assets/cards/" + card.cardCode + ".png"' alt="">
                </div>
            </div>
        </div>
    </div>

</template>

<script>
    import cards from '../assets/cards/set1-en_us.json'
    import router from '../router'

    export default {
        data() {
            return {
                cards: cards,
                search: '',
                regions: ['Demacia', 'Noxus'],
                cost: [7],
                attack: [3, 5],
                health: [4, 7],
                rarity: ['Champion']
            }
        },
        methods: {
            specificCard(cardCode){
                router.push({ name: 'specificCard', params: { cardCode: cardCode } })
            }
        },
        computed: {
            filteredByName(){
                return this.cards.filter((card) => {
                    return card.name.match(this.search)
                })
            },
            filteredByRegion(){
                return this.cards.filter((card) => {
                    return this.regions.includes(card.region)
                })
            },
            filteredByCost(){
                return this.cards.filter((card) => {
                    return this.cost.includes(card.cost)
                })
            },
            filteredByRarity(){
                return this.cards.filter((card) => {
                    return this.rarity.includes(card.rarity)
                })
            },
            filteredByAttack(){
                return this.cards.filter((card) => {
                    return this.attack.includes(card.attack)
                })
            },
            filteredByHealth(){
                return this.cards.filter((card) => {
                    return this.health.includes(card.health)
                })
            },
        }
    }
</script> 

Information

  1. Place all your filter methods in the methods attribute on the vue instance
  2. Create a way to enable/disable the filters
  3. Create a computed property that looks at your #2 in this list and applies the proper filters accordingly

My rough example

 new Vue({ el: "#app", data () { return { filterEnabler: { search: false, sort: false }, formInputs: { searchText: '' }, entries: [ 'vue', 'react', 'angular', 'svelte' ] } }, computed: { filteredEntries () { let { entries, filterEnabler } = this entries = entries.slice(0) if (filterEnabler.search) entries = this.searchFilter(entries) if (filterEnabler.sort) entries = this.sortFilter(entries) return entries } }, methods: { searchFilter (entries) { return entries.filter(entry => entry.indexOf(this.formInputs.searchText) !== -1) }, sortFilter (entries) { return entries.sort() } } });
 <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script> <div id="app"> <div class="filters"> <div class="search-filter"> <input type="checkbox" v-model="filterEnabler.search" /> Search Filter <div v-if="filterEnabler.search"> <input placeholder="type here" type="text" v-model="formInputs.searchText" /> </div> </div> <div class="sort-filter"> <input type="checkbox" v-model="filterEnabler.sort" /> Sort Filter </div> </div> <ul> <li v-for="entry in filteredEntries" :key="entry">{{entry}}</li> </ul> </div>

In my example, you can see this I have 2 filters, search and sort - when one of their filterEnablers is toggeled true , it will apply all the enabled filters to the data and then return a new, separate array (very important, try not to mutate your source of truth, in my case, that's entries )

Hope this helps!

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