likes
comments
collection
share

贷款计算器简版实现

作者站长头像
站长
· 阅读数 24

背景

还了几年房贷了,想想自己如果提前还贷,以及转成公积金的方式自己后面每个月分别需要还多少钱,哪种方式让自己利息更少,每个月压力更小,有一个明确可以量化的预期。

在使用支付宝或者微信小程序贷款计算器的过程中要么是有广告要么就是不好调整相关利率和参数,所以自己写一个简易的版本也是不错的,实用为主。

准备阶段

概念

  • 等额本金是指在还款期限内,每个月偿还的本金数额相同,由于每个月偿还的本金数额减少,因此每个月的利息数额也逐渐减少。这种方式在还款期限内每月还款金额逐渐减少,能够帮助借款人更好地规划自己的预期支出。

  • 等额本息是指在还款期限内,每个月偿还的利息和本金数额相同,由于每个月偿还的利息数额相同,因此每个月偿还的本金数额也相同。这种方式在还款期限内每月还款金额保持不变,能够帮助借款人更好地规划自己的预期支出。

相关计算公式

等额本息

  • 等额本息 每月还本付息金额=[贷款本金×月利率×(1+月利率)^还款月数]÷[(1+月利率)^还款月数-1]

  • 每月应还利息=贷款本金×月利率×〔(1+月利率)^还款月数-(1+月利率)^(还款月序号-1)〕÷〔(1+月利率)^还款月数-1〕

  • 每月应还本金=贷款本金×月利率×(1+月利率)^(还款月序号-1)÷〔(1+月利率)^还款月数-1〕

  • 总利息=还款月数×每月月供额-贷款本金

等额本金

  • 等额本金的计算公式为: 每月还本付息金额=(本金/还款月数)+(本金-累计已还本金)×月利率

  • 每月应还本金=贷款本金÷还款月数

  • 每月应还利息=剩余本金×月利率=(贷款本金-已归还本金累计额)×月利率。

  • 每月月供递减额=每月应还本金×月利率=贷款本金÷还款月数×月利率

  • 总利息=(还款月数+1)×贷款总额×月利率÷2

代码(本地可以直接运行)

预览

贷款计算器简版实现

代码

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      .container {
        width: 1440px;
        height: auto;
        margin: auto;
        padding: 20px;
      }
    </style>
    <link href="https://cdn.bootcdn.net/ajax/libs/element-ui/2.15.13/theme-chalk/index.min.css" rel="stylesheet" />
  </head>
  <body>
    <div id="app">
      <div class="container">
        <el-form ref="form" label-width="120px">
          <el-form-item label="总金额(万):" >
            <el-input v-model="total"></el-input>
          </el-form-item>

          <el-form-item label="利率(%):">
            <el-input v-model="rate"></el-input>
          </el-form-item>

          <el-form-item label="期限(年):">
            <el-input v-model="year"></el-input>
          </el-form-item>

          <el-form-item label="月供:">
            <el-input v-model="result"></el-input>
          </el-form-item>

          <el-form-item label="还款总额:">
            <el-input v-model="total_er"></el-input>
          </el-form-item>

          <el-form-item label="利息总额:">
            <el-input v-model="total_lixi"></el-input>
          </el-form-item>

          <el-form-item label="递减金额:" :style="isCapital ? 'opacity:1' :'opacity:0'">
            <el-input v-model="decAmount"></el-input>
          </el-form-item>
        </el-form>

        <div class="calc-btn">
          <el-button @click="compontedBX">计算等额本息</el-button>
          <el-button @click="compontedBJ">计算等额本金</el-button>
        </div>

        <div class="his-block">
          <div style="margin: 10px; text-align: center">
            <el-tag type="success">汇总信息</el-tag>
          </div>

          <el-card class="box-card">
            <el-table :data="recordList" border style="width: 100%">
              <el-table-column prop="total_er" label="还款总额"> </el-table-column>
              <el-table-column prop="total_lixi" label="还款利息"> </el-table-column>
              <el-table-column prop="rate" label="利率"> </el-table-column>
              <el-table-column prop="type" label="类型">
                <template slot-scope="scope"> {{scope.row.type>1?'等额本金':'等额本息'}} </template>
              </el-table-column>
            </el-table>
          </el-card>
        </div>

        <div style="margin: 10px; text-align: center">
          <el-tag type="success">还款信息</el-tag>
        </div>
        <el-card class="box-card">
          <el-table :data="history_data" border style="width: 100%">
            <el-table-column prop="month" label="月份" width="80px"> </el-table-column>
            <el-table-column prop="monthPay" label="月供"> </el-table-column>
            <el-table-column prop="lastPay" label="剩余贷款"> </el-table-column>
          </el-table>
        </el-card>
      </div>
    </div>
    <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.10/vue.common.dev.js"></script>
    <script src="https://cdn.bootcdn.net/ajax/libs/element-ui/2.15.13/index.min.js"></script>
    <script>
      var vm = new Vue({
        el: '#app',
        data() {
          return {
            total: 10,
            rate: 4.9,
            year: 10,
            result: '',
            list: [],
            total_lixi: '',
            total_er: '',
            // 递减金额
            decAmount: '',
            isCapital: false,
            recordList: [],
          }
        },
        computed: {
          c_total() {
            return this.total * 10000
          },
          c_rate() {
            return this.rate / 100 / 12
          },
          c_mouths() {
            return this.year * 12
          },
          history_data() {
            console.log(this.list, 'list')
            return this.list.map((m, inx) => {
              return {
                month: inx + 1,
                monthPay: m.res,
                lastPay: this.filterSmallMoney(m.yu),
              }
            })
          },
        },
        methods: {
          //  等额本息  每月还本付息金额=[贷款本金×月利率×(1+月利率)^还款月数]÷[(1+月利率)^还款月数-1]

          //  每月应还利息=贷款本金×月利率×〔(1+月利率)^还款月数-(1+月利率)^(还款月序号-1)〕÷〔(1+月利率)^还款月数-1〕

          //  每月应还本金=贷款本金×月利率×(1+月利率)^(还款月序号-1)÷〔(1+月利率)^还款月数-1〕

          //  总利息=还款月数×每月月供额-贷款本金

          compontedBX() {
            this.isCapital = false
            this.clearList()
            // 每月月供       贷款本金      月利率                                       还款总月数 例: 10 年 就是 10 * 12 = 120 期
            let result = (this.c_total * this.c_rate * Math.pow(1 + this.c_rate, this.c_mouths)) / (Math.pow(1 + this.c_rate, this.c_mouths) - 1)

            this.result = result.toFixed(2)
            let total_rate = result.toFixed(2) * this.c_mouths
            for (let i = 1; i <= this.c_mouths; i++) {
              this.list.push({
                res: result.toFixed(2),
                yu: (total_rate - result.toFixed(2) * i).toFixed(2),
              })
            }
            // 总利息
            this.total_lixi = (this.c_mouths * result - this.c_total).toFixed(2)
            this.total_er = (Number(this.total_lixi) + Number(this.c_total)).toFixed(2)
            this.splitSmallMoney()

            // 统计历史记录
            const data = {
              total_er: this.total_er,
              total_lixi: this.total_lixi,
              rate: this.rate,
              type: 1, // 1等额本息 2等额本金
            }
            this.recordList.push(data)
          },

          //   等额本金的计算公式为: 每月还本付息金额=(本金/还款月数)+(本金-累计已还本金)×月利率

          //    每月应还本金=贷款本金÷还款月数

          //  每月应还利息=剩余本金×月利率=(贷款本金-已归还本金累计额)×月利率。

          // 每月月供递减额=每月应还本金×月利率=贷款本金÷还款月数×月利率

          //  总利息=(还款月数+1)×贷款总额×月利率÷2
          compontedBJ() {
            this.isCapital = true
            this.clearList()
            // 月供
            let res
            // 已还本金
            let yhbj = 0
            // 已还的本息
            let yhbx = 0
            // 贷款本金                还款月数                月利率
            let total = this.c_total,
              mouths = this.c_mouths,
              rate = this.c_rate
            res = total / mouths + (total - yhbj) * rate
            res = res.toFixed(2)
            yhbx = res + yhbx
            this.result = res
            this.total_lixi = ((mouths + 1) * total * rate) / 2
            this.total_er = this.total_lixi + this.c_total
            this.list.push({ res: res, yu: (this.total_er - yhbx).toFixed(2) })
            this.decAmount = ((total / mouths) * rate).toFixed(2)
            for (let i = 1; i <= mouths; i++) {
              yhbj = (total / mouths) * i
              res = total / mouths + (total - yhbj) * rate
              res = res.toFixed(2)
              yhbx = Number(res) + Number(yhbx)
              this.list.push({
                res: res,
                yu: (this.total_er - yhbx).toFixed(2),
              })
            }
            this.splitSmallMoney()
            // 统计历史记录
            const data = {
              total_er: this.total_er,
              total_lixi: this.total_lixi,
              rate: this.rate,
              type: 2, // 1等额本息 2等额本金
            }
            this.recordList.push(data)
          },

          clearList() {
            this.list = []
            this.decAmount = ''
          },

          splitSmallMoney() {
            // 处理末尾还款数额太少出现增项的问题
            this.list = this.list.splice(0, this.year * 12)
          },

          filterSmallMoney(m) {
            if (m < 1) return 0
            return m
          },
        },
      })
    </script>
  </body>
</html>

总结

远离房赌毒,守护健康人生!