如何在Vue.js中计算嵌套数组的滚动余额(Running Balance)
修正Vue中滚动余额计算的
getRunningBal方法 需求说明
需要计算滚动余额,公式为:滚动余额 = Amort - 累计AmountApplied,期望输出表格格式如下:
Line Amort Total Payment Running Balance 1 30250 10000 20250.00 30250 20250 0.00 2 30250 30250 0.00
现有Vue模板通过v-for嵌套遍历soaData和subPayments,调用getRunningBal方法计算滚动余额,但当前方法无法得到正确结果。
原方法问题分析
原getRunningBal代码存在以下问题:
- 循环内直接
return,仅执行一次循环就返回结果,无法完成累计计算 - 逻辑错误:直接累加
AmountApplied,未按照Amort - 累计AmountApplied的公式计算 - 未针对当前遍历的
subPayment位置计算累计值,无法得到对应行的滚动余额
原方法代码:
getRunningBal(subPayments, amortId){ let subpayCount = Object.values(this.soaData[amortId].subPayments).length let data = Object.values(this.soaData[amortId].subPayments) var total = 0; for(let i=0; i < subpayCount; i++){ return total += data[i].AmountApplied) } }
数据结构参考
{ "267": { "Ndays": 9, "DueDate": "2023-02-15", "Amort": 30250, "CheckNumber": "12341431", "DatePaid": "2022-10-07", "CheckStatus": "INVALID", "TotalRCF": null, "TotalDPF": null, "TotalHF": null, "amortCode": "11-9", "amortId": 267, "paymentAppliedID": 77, "DateDeposited": "2022-10-08", "ReDepositDate": null, "AmountApplied": 20250, "TotalPayables": 30250, "TotalPaymentsApplied": 30250, "subPayments": { "75": { "AmountApplied": 10000, "isCheck": 0, "amortCode": "11-9", "ReDepositDate": null, "DateDeposited": null, "DatePaid": "2022-10-07", "CheckNumber": null, "paymentAppliedID": 75, "TotalPayables": 30250 }, "77": { "AmountApplied": 20250, "isCheck": 1, "amortCode": "11-9", "ReDepositDate": null, "DateDeposited": "2022-10-08", "DatePaid": "2022-10-07", "CheckNumber": "12341431", "paymentAppliedID": 77, "TotalPayables": 30250 } } }, "270": { "Ndays": 12, "DueDate": "2023-03-30", "Amort": 30250, "CheckNumber": null, "DatePaid": "2022-10-07", "CheckStatus": "CASHREP", "TotalRCF": null, "TotalDPF": null, "TotalHF": null, "amortCode": "", "amortId": 270, "paymentAppliedID": 79, "DateDeposited": null, "ReDepositDate": null, "AmountApplied": 30250, "TotalPayables": 30250, "TotalPaymentsApplied": 30250, "subPayments": { "79": { "AmountApplied": 30250, "isCheck": 0, "amortCode": "11-12", "ReDepositDate": null, "DateDeposited": null, "DatePaid": "2022-10-07", "CheckNumber": null, "paymentAppliedID": 79, "TotalPayables": 30250 } } } }
修正后的方法实现
修正后的方法会针对当前遍历的subPayment位置,计算到该位置的累计AmountApplied,再用Amort减去累计值得到滚动余额:
getRunningBal(amortId, currentIndex) { // 获取当前amort项的基础数据 const amortItem = this.soaData[amortId]; // 将subPayments转为数组,按paymentAppliedID排序保证顺序 const subPaymentsArr = Object.values(amortItem.subPayments).sort((a, b) => a.paymentAppliedID - b.paymentAppliedID); // 计算到当前索引的累计AmountApplied let totalApplied = 0; for (let i = 0; i <= currentIndex; i++) { totalApplied += subPaymentsArr[i].AmountApplied; } // 计算滚动余额,保留两位小数 const runningBalance = amortItem.Amort - totalApplied; return runningBalance.toFixed(2); }
模板调用示例
在v-for遍历的时候需要传递当前的索引:
<div v-for="(amortItem, amortId) in soaData" :key="amortId"> <div v-for="(subPayment, idx) in Object.values(amortItem.subPayments).sort((a,b)=>a.paymentAppliedID-b.paymentAppliedID)" :key="subPayment.paymentAppliedID"> <!-- 其他列 --> <td>{{ getRunningBal(amortId, idx) }}</td> </div> </div>
逻辑说明
- 将
subPayments对象转为数组并排序,确保支付顺序符合业务逻辑(这里用paymentAppliedID排序,可根据实际需求调整) - 遍历到当前索引的所有
subPayment,累计AmountApplied - 用当前
amortItem的Amort减去累计值,得到滚动余额并保留两位小数
内容的提问来源于stack exchange,提问作者Not a Pro
相关产品推荐
相关产品推荐

