javascript - 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
- Place all your filter methods in the
methods
attribute on the vue instance - Create a way to enable/disable the filters
- 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!
推荐阅读
- html - 如何让最底部的 div 停止在页脚处浮动
- excel - 单击工作表时触发工作表宏
- google-cloud-platform - GCP API 仪表板不计算我的所有请求
- python - 如果没有命令 python manage.py runcrons,Cron 不会执行我的任务
- vb.net - 两个 VSTO 加载项能否处理相同的 Outlook 应用程序事件 (application.newmailex)
- .net - .NET 正则表达式不正确匹配
- algorithm - 考虑到某些延误,在最坏的情况下到达目的地的最短时间?
- .net-core - Visual Studio 自定义项目模板 - applicationUrl 端口号
- linux - 对不同终端的命令
- angular - 如何使用 MatTabChangeEvent 获取内容