You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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>

逻辑说明

  1. 将subPayments对象转为数组并排序,确保支付顺序符合业务逻辑(这里用paymentAppliedID排序,可根据实际需求调整)
  2. 遍历到当前索引的所有subPayment,累计AmountApplied
  3. 用当前amortItem的Amort减去累计值,得到滚动余额并保留两位小数

内容的提问来源于stack exchange,提问作者Not a Pro

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 03:50:33