聊一聊前端格式化数据的一些心得

639 阅读2分钟

一、引言

最近一直弄后台管理系统,因为大都是一些表格项,所以经常会用到一些格式化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)
}