一、引言
最近一直弄后台管理系统,因为大都是一些表格项,所以经常会用到一些格式化formatter,这里聊一聊自己封装并且经常使用的一些格式化函数。包含一些自己的解决方案,例如千分化、精度缺失,以及对于函数式编程的初体验。
二、空数据的处理
一般表格的内容,如果后台不返回数据或者返回null,我这里通常会使用横杠"-"作为标识。
// 对于空数据,返回'-'
export function commonFormatter(cellValue) {
if (!cellValue && cellValue !== 0) {
return '-'
}
return cellValue
}
三、添加单位
一般类似于表格数据中有需要补充单位的,例如5%,这种需要添加%这个单位
// 补充单位
export function padUnit(unit) {
return function(num) {
if (!num && num !== 0) {
return ''
}
return num + unit
}
}
四、千分化
千分化在表格数据中还是比较常见的,例如10,000
export function toThousand(num) {
const parseNum = Number.parseFloat(num)
if (Number.isNaN(parseNum)) {
return ''
}
const numStr = num.toString()
return numStr.replace(/(\d)(?=(\d{3})+\b)/g, '$1,')
}
五、保留小数点后xx位
保留小数点后xx位,这里直接调用的是toFixed方法,但这里大家千万要注意toFixed不是四舍五入,使用是一种银行家舍入,四舍六入五成双
// 小数点格式化
export function toFixed(digit) {
return function(num) {
const parseNum = Number.parseFloat(num)
if (Number.isNaN(parseNum)) {
return ''
}
return parseNum.toFixed(digit)
}
六、将"分"转换为"元"
因为之前遇到的很多项目,金额在后台数据库存储是以分为单位,所以前端在展示给用户的话,需要前端将数据整除100。但这里就又遇到了一个问题,精度缺失。我解决的方法是调用现成的库mathjs,对四则运算进行二次封装。
// 安装依赖
npm install mathjs
// 二次封装成math.js文件
import * as $math from 'mathjs'
function comp(_func, args) {
let t = $math.chain($math.bignumber(args[0]))
for (let i = 1; i < args.length; i++) {
t = t[_func]($math.bignumber(args[i]))
}
// 防止超过6位使用科学计数法
return parseFloat(t.done())
}
export function add() {
return comp('add', arguments)
}
export function subtract() {
return comp('subtract', arguments)
}
export function multiply() {
return comp('multiply', arguments)
}
export function divide() {
return comp('divide', arguments)
}
import { divide } from './math.js'
// 将分转换为元
export function penyToYuan(num) {
const parseNum = Number.parseFloat(num)
if (Number.isNaN(parseNum)) {
return ''
}
return divide(parseNum, 100)
}
七、组合
在处理数据的时候,我们可能一次性要使用多种组合,类似于在处理金额的时候,例如1,234.56元,先将分转化为元,再保留两位小数,再千分,再加个单位元。
好像我们现在已经具备所有的功能了,就类似于我们已经有很多积木了,但怎么才能把这些积木搭起来呢?最终我遇到了《函数式编程》
虽然一直使用的是Vue,但久闻redux的compose函数的大名,这个函数可以将一些系列的函数从右往左组合在一起变成一个函数。
// compose函数
function compose(...funcs) {
if (funcs.length === 0) {
return arg => arg
}
if (funcs.length === 1) {
return funcs[0]
}
return funcs.reduce((a, b) => (...args) => a(b(...args)))
}
这里我们不对函数式编程进行太多讲解,举一个简单的小例子:求两数之和的平均值
// 求和函数
const sum = (a, b) => a + b
// 除2函数
const divide = total => total / 2
// 将两个函数从右往左依次组合,前一个函数的结果,会作为下一个函数的入参
const fn = compose(divide, sum)
// 执行 => 1.5
fn(1, 2)
八、费率格式化
// 费率格式化(保留两位小数,并加上%单位)
export function rateFormatter(value) {
return compose(commonFormatter, padUnit('%'), toFixed(2))(value)
}
九、金额格式化
// 金额通用格式化(将分除100转化为元, 保留两位小数,千分化, 加上单位元)
export function priceFormatter(value) {
return compose(commonFormatter, padUnit('元'), toThousand, toFixed(2), penyToYuan)(value)
}