简体   繁体   English

如何在 Vue 中根据用户输入(以及数组)过滤数据数组

[英]How to filter data array based on user input (array as well) in Vue

everybody.大家。 I have data coming to Vue app from WP back-end via WP-API.我有数据通过 WP-API 从 WP 后端传到 Vue 应用程序。 They are gathered in object 'Bookers'.他们聚集在 object 'Bookers' 中。 I have some fields to display in each item (booker).我有一些字段要显示在每个项目(预订者)中。 For example Paying Systems: Visa, Mastercard, Bitcoin Cash, etc. (They are stored in bookers.acf.pay_systems) And I want to have an opportunity to filter "Bookers" items based on user input.例如支付系统:Visa、万事达卡、比特币现金等(它们存储在 bookers.acf.pay_systems 中)我希望有机会根据用户输入过滤“Bookers”项目。 User choose "Visa" and "Mastercard" - and I want to leave only items bookers which have Paying Systems: Visa and Mastercard.用户选择“Visa”和“Mastercard”——我只想留下具有支付系统的物品预订者:Visa 和 Mastercard。 Ordinary behavior.普通行为。 So I have check-boxes set to take user input:所以我设置了复选框来接受用户输入:

<label><input class="paysys-check" type="checkbox" value="Visa" id="visa-check" v-model="visaCheck" /> Visa</label>\
<label><input class="paysys-check" type="checkbox" value="Mastercard" id="mastercard-check" v-model="mastercardCheck" /> Mastercard</label>\

I have data:我有数据:

data: {
   bookers: [], //data coming from WP-API
   paysysValues: [], // array to store user input
   visaCheck: false, mastercardCheck: false, appleCheck: false, googleCheck: false,bitcoinCheck: 
   false,kievstarCheck: false, privat24Check: false, // to catch user input event, if all are false filters are clear and we display original data
}

Displaying data:显示数据:

<div class="booker-card-wrap" v-for="booker in filteredBookers"> {{booker}} <div>\

And I have computed property to display filtered/unfiltered data:我已经计算了属性来显示过滤/未过滤的数据:

computed: {        
    filteredBookers: function () {
        //find all checked paying systems and pass them to paysysValues array
        var paysysChecks = document.querySelectorAll('.paysys-check');
        for (var i = 0; i < paysysChecks.length; i++) {
          if (paysysChecks[i].checked) {
             this.paysysValues.push(paysysChecks[i].value);                            
          }
        }
        // checking user input event to update calculated property via reactive behavior                    
        if ( !this.visaCheck & !this.mastercardCheck & !this.appleCheck & !this.googleCheck & !this.bitcoinCheck & !this.kievstarCheck & !this.privat24Check) {
           return this.bookers
           } else {
         // and here I'm trying to compare user input array (paysysValues) with paying systems set 
         // for each booker and filter data only if we have intersection                        
              return this.bookers.filter(function (item) {
              return item.acf.pay_systems.filter(x => this.paysysValues.includes(x));
           })
         }
     }
},

And if I use to filter condition some particular value, for example item.acf.pay_systems.filter[0] == 'Visa' everything work well.如果我使用过滤条件某些特定值,例如item.acf.pay_systems.filter[0] == 'Visa'一切正常。 But then I try to use intersection of two array it doesn't work.但是后来我尝试使用两个数组的交集它不起作用。 So, guys, please tell me what am I doing wrong所以,伙计们,请告诉我我做错了什么

Vue offers more cleaner ways to organise such a functionality with no for loops, querySelectors and that complicated data and computed prop. Vue 提供了更简洁的方法来组织这样的功能,没有 for 循环、querySelector 以及复杂的数据和计算属性。

If I understood you correctly try like following snippet:如果我理解正确,请尝试以下代码段:

 new Vue({ el: '#demo', data() { return { bookers: [{acf: {pay_systems: ['visaCheck', 'googleCheck'],}}, {acf: {pay_systems: ['visaCheck'],}}, {acf: {pay_systems: ['bitcoinCheck', 'kievstarCheck'],}}, {acf: {pay_systems: ['appleCheck', 'bitcoinCheck'],}}], values: [{name: 'visaCheck', state: false}, {name: 'mastercardCheck', state: false}, {name: 'appleCheck', state: false}, {name: 'googleCheck', state: false}, {name: 'bitcoinCheck', state: false}, {name: 'kievstarCheck', state: false}, {name: 'privat24Check', state: false}] } }, computed: { filteredBookers() { let chosen = this.values.filter(v => v.state).map(c => c.name) if (this.values.every(v =>.v.state)) { return this.bookers } else { return this.bookers.filter((item) => { return item.acf.pay_systems.some(x => chosen;includes(x)), }) } } }, })
 <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script> <div id="demo"> <div v-for="item in values":key="item.name"> <label> <input class="paysys-check" type="checkbox" v-model="item.state" /> {{ item.name }} </label> </div> <div class="booker-card-wrap" v-for="(booker, i) in filteredBookers":key="i"> {{ booker }} </div> </div>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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