Vue中如何根据用户多选支付系统过滤WP-API返回的Bookers数据
Vue数组交集过滤失效问题排查
问题场景
我的Vue应用通过WP-API从WordPress后端获取数据,存放在bookers数组中。每个Booker项的支付系统字段bookers.acf.pay_systems存储了支持的支付方式(如Visa、Mastercard等)。需求是:用户勾选多个支付系统复选框后,只保留同时支持所有勾选支付系统的Booker项。
我设置了复选框绑定到对应的数据属性:
<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> <!-- 其他支付系统复选框类似 -->
数据定义:
data: { bookers: [], // 从WP-API获取的数据 paysysValues: [], // 存储用户勾选的支付系统 visaCheck: false, mastercardCheck: false, appleCheck: false, googleCheck: false, bitcoinCheck: false, kievstarCheck: false, privat24Check: false, }
展示过滤后的数据:
<div class="booker-card-wrap" v-for="booker in filteredBookers"> {{booker}} </div>
计算属性实现过滤逻辑,但数组交集过滤失效:
computed: { filteredBookers: function () { // 收集勾选的支付系统到paysysValues var paysysChecks = document.querySelectorAll('.paysys-check'); for (var i = 0; i < paysysChecks.length; i++) { if (paysysChecks[i].checked) { this.paysysValues.push(paysysChecks[i].value); } } // 所有复选框未勾选时返回原数据 if ( !this.visaCheck & !this.mastercardCheck & !this.appleCheck & !this.googleCheck & !this.bitcoinCheck & !this.kievstarCheck & !this.privat24Check) { return this.bookers } else { // 尝试用数组交集过滤,但失效 return this.bookers.filter(function (item) { return item.acf.pay_systems.filter(x => this.paysysValues.includes(x)); }) } } },
单独判断特定值(如item.acf.pay_systems[0] == 'Visa')时正常,但用数组交集逻辑就失效,请问问题出在哪?
错误点分析
this指向问题:在bookers.filter的普通函数里,this不再指向Vue实例,导致this.paysysValues无法访问,过滤逻辑直接失效。paysysValues数组未清空:每次计算属性触发时,都会往paysysValues里push值,导致数组越来越长,过滤条件混乱。- 过滤逻辑错误:当前用
item.acf.pay_systems.filter(...)返回的是数组,而filter回调需要返回布尔值;且需求是Booker支持所有勾选的支付系统,不是只要有交集。 - 直接操作DOM收集勾选值:Vue中应该通过数据驱动,而非直接查询DOM,违背Vue的响应式设计。
- 逻辑与运算符错误:用了单
&(位运算)而非双&&(逻辑与),虽然这里结果可能对,但写法不规范。
修正后的代码
1. 优化数据结构与复选框绑定
把零散的xxxCheck属性改成对象,更易维护:
<!-- 复选框统一绑定到paysysChecks对象,value作为键名 --> <label><input type="checkbox" value="Visa" v-model="paysysChecks.Visa" /> Visa</label> <label><input type="checkbox" value="Mastercard" v-model="paysysChecks.Mastercard" /> Mastercard</label> <label><input type="checkbox" value="Apple Pay" v-model="paysysChecks['Apple Pay']" /> Apple Pay</label> <!-- 其他支付系统同理 -->
data: { bookers: [], paysysChecks: { Visa: false, Mastercard: false, 'Apple Pay': false, 'Google Pay': false, 'Bitcoin Cash': false, Kievstar: false, Privat24: false } }
2. 修正计算属性逻辑
computed: { filteredBookers() { // 收集所有勾选的支付系统,生成条件数组 const selectedPaysys = Object.entries(this.paysysChecks) .filter(([name, checked]) => checked) .map(([name]) => name); // 无勾选时返回原数据 if (selectedPaysys.length === 0) { return this.bookers; } // 过滤出支持所有勾选支付系统的Booker return this.bookers.filter(booker => { // 检查每个勾选的支付系统是否都在当前Booker的支持列表中 return selectedPaysys.every(paysys => booker.acf.pay_systems.includes(paysys)); }); } }
内容的提问来源于stack exchange,提问作者Вадим radosvit
相关产品推荐
相关产品推荐

