news 2026/7/14 20:44:01

Vue el-table 表尾合计行

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Vue el-table 表尾合计行
问题:

前端在处理后端接口返回的列表数据进行表尾合计行统计,由于返回的金额不固定,有小数,整数,大数值等等,会出现累计计算数值精度丢失的问题,导致页面数据看起来是错的。

原因:

在JavaScript中,Number.MAX_SAFE_INTEGER是一个常量,其值为9007199254740991(2^53 - 1),代表JavaScript中可以安全表示的最大整数。这意味着任何大于Number.MAX_SAFE_INTEGER的整数在进行数学运算时可能会失去精度,因为JavaScript使用IEEE 754标准的64位浮点数表示数字,其中包括一个符号位、11位指数位和52位尾数位。

重写el-table 表尾合计行方法:
<template> <div class="table-container"> <el-table :data="tableData" show-summary :summary-method="getSummaries" style="width: 100%"> <el-table-column prop="id" label="ID" width="120"></el-table-column> <el-table-column prop="month" label="月份" width="120"></el-table-column> <el-table-column prop="name" label="姓名"></el-table-column> <el-table-column prop="amount1" label="整数金额" width="120"></el-table-column> <el-table-column prop="amount2" label="小数金额" width="120"></el-table-column> <el-table-column prop="amount3" label="混合金额" width="200"></el-table-column> </el-table> </div> </template> <script> export default { name: 'TableComponent', data() { return { tableData: [ { id: '12987122', month: '2026-02', name: '王小虎', amount1: '234', amount2: '3.2', amount3: '0.11' }, { id: '12987123', month: '2026-01', name: '王小虎', amount1: '165', amount2: '4.43', amount3: '0.88' }, { id: '12987124', month: '2025-12', name: '王小虎', amount1: '324', amount2: '1.9', amount3: '2' }, { id: '12987125', month: '2025-11', name: '王小虎', amount1: '621', amount2: '2.2', amount3: '123456789123456789' }, { id: '12987126', month: '2025-10', name: '王小虎', amount1: '539', amount2: '4.1', amount3: '887654321987654321' } ] }; }, methods: { getSummaries(param) { const { columns, data } = param; const sums = []; columns.forEach((column, index) => { if (index === 0) { sums[index] = '合计'; return; } const values = data.map(item => Number(item[column.property])); if (column.property === 'amount3') { // 对amount3字段进行高精度计算 const total = this.calculateHighPrecisionSum(data.map(item => item.amount3)); sums[index] = total; } else if (!values.every(value => isNaN(value))) { const precisions = []; let notNumber = true; values.forEach(value => { if (!isNaN(value)) { notNumber = false; const decimal = value.toString().split('.')[1]; precisions.push(decimal ? decimal.length : 0); } }); if (!notNumber) { const precision = Math.max(...precisions); sums[index] = values.reduce((prev, curr) => { const value = Number(curr); if (!isNaN(value)) { return parseFloat((prev + value).toFixed(Math.min(precision, 20))); } else { return prev; } }, 0); } else { sums[index] = 'N/A'; } } else { sums[index] = 'N/A'; } }); return sums; }, // 高精度计算方法,处理大数和小数的精确相加 calculateHighPrecisionSum(amounts) { if (!amounts || amounts.length === 0) return '0'; // 使用数组来存储每一位数字,从低位到高位 let result = []; let maxDecimalPlaces = 0; // 先确定最大的小数位数 amounts.forEach(amount => { const parts = amount.split('.'); if (parts.length > 1) { maxDecimalPlaces = Math.max(maxDecimalPlaces, parts[1].length); } }); // 将所有数字转换为整数进行计算(乘以10^maxDecimalPlaces) const integers = amounts.map(amount => { const parts = amount.split('.'); let integerPart = parts[0]; let decimalPart = parts[1] || ''; // 补齐小数位 while (decimalPart.length < maxDecimalPlaces) { decimalPart += '0'; } return integerPart + decimalPart; }); // 从右到左逐位相加 let carry = 0; let maxLength = Math.max(...integers.map(num => num.length)); // 补齐位数 for (let i = 0; i < integers.length; i++) { while (integers[i].length < maxLength) { integers[i] = '0' + integers[i]; } } // 逐位相加 for (let i = maxLength - 1; i >= 0; i--) { let sum = carry; for (let j = 0; j < integers.length; j++) { sum += parseInt(integers[j][i] || '0'); } result.unshift(sum % 10); carry = Math.floor(sum / 10); } // 处理最后的进位 while (carry > 0) { result.unshift(carry % 10); carry = Math.floor(carry / 10); } // 转换回小数形式 let resultStr = result.join(''); // 如果需要小数点,插入小数点 if (maxDecimalPlaces > 0) { if (resultStr.length <= maxDecimalPlaces) { // 如果结果长度小于小数位数,前面补0 while (resultStr.length < maxDecimalPlaces + 1) { resultStr = '0' + resultStr; } } const decimalIndex = resultStr.length - maxDecimalPlaces; resultStr = resultStr.substring(0, decimalIndex) + '.' + resultStr.substring(decimalIndex); // 去除末尾多余的0 resultStr = resultStr.replace(/\.?0+$/, ''); // 如果小数点在最后,去掉小数点 resultStr = resultStr.replace(/\.$/, ''); } // 去除开头的0(但保留至少一个数字) // 页面eslint校验报错可删除 resultStr = resultStr.replace(/+/, '') || '0'; return resultStr; } } }; </script> <style scoped> .table-container { padding: 20px; background-color: #fff; border-radius: 8px; box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1); } </style>
代码逻辑说明:
  1. 实现了Vue.js环境下的表格组件,包含表尾合计行功能
  2. 针对混合金额字段amount3,实现了高精度计算方法,支持小数、整数和大数的精确相加
  3. 使用字符串操作和逐位计算的方式,确保大数计算时不会丢失精度
  4. 合计计算从数值的最后面往前一步步计算,保证计算准确性
  5. 返回总金额的字符串格式,保持原始数据的精度特征
  6. 包含完整的样式设计,提供现代化的UI界面

记录一下,有好的方法可以评论区说说~

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/14 16:20:52

提示工程架构师进阶:打造企业级代码生成工具实战

提示工程架构师进阶:打造企业级代码生成工具实战 一、引言 在当今软件开发的快节奏环境中,提高开发效率和质量是每个企业追求的目标。代码生成工具作为一种能够自动化生成部分代码的利器,正逐渐在企业级开发中崭露头角。对于提示工程架构师而言,打造企业级代码生成工具不…

作者头像 李华
网站建设 2026/7/8 7:53:29

自建一个Agent很难吗?一语道破,万语难明

最近花了一周左右的时间给内部的一个传统研发平台接入了 Agent 开发的能力&#xff0c;很多同学对 Agent 的底层实现非常感兴趣&#xff0c;所以此篇给大家介绍下我是怎么做的&#xff0c;希望能对想自建 Agent 的同学有所启发。 因人力原因&#xff0c;有些细节方案问题没太做…

作者头像 李华
网站建设 2026/7/1 21:24:07

【第1章·第14节】自适应PID控制器的simulink建模与仿真1——理论分析

目录 1.自适应PID控制器概述 2.自适应PID控制器的理论分析 2.1 PID控制器误差 2.2 自适应PID控制器调整策略 2.3 自适应PID控制参数更新 1.自适应PID控制器概述 自适应PID控制器核心是通过实时反馈误差,动态调整比例系数kp、积分系数ki、微分系数kd,解决传统PID固定参数…

作者头像 李华
网站建设 2026/7/3 3:57:13

1.5亿,AI原生城市服务平台建设项目

1 月 30 日&#xff0c;福州市鼓楼区AI原生城市服务平台建设项目&#xff08;一期&#xff09;中标公告&#xff0c;中标金额&#xff1a;15084.0636万元&#xff0c;中标人&#xff1a;中国移动通信集团福建有限公司福州分公司。一、项目信息&#xff1a;项目名称&#xff1a;…

作者头像 李华
网站建设 2026/6/28 23:55:18

Spring Boot 应用启动速度优化全攻略

一、引言&#xff1a;Spring Boot 启动慢的常见痛点1.1 启动慢的现象本地开发时每次修改代码后重启需要30秒以上测试环境部署时启动时间超过1分钟生产环境容器启动缓慢影响弹性伸缩CI/CD流水线中构建-启动-测试周期过长1.2 启动速度的重要性开发效率&#xff1a;快速反馈循环是…

作者头像 李华