如何用Vue实现输入框金额格式化呢?我们都知道,以元为单位时,金额往往是需要保存到小数点后两位的,用来表示角和分,并且为了能对金额位数一目了然,往往需要三位为一个间隔,用逗号分隔金额位数。基于以上需求,我们现在用Vue来实现功能。

首先我们需要知道,加了分隔符的金额就不再是数字类型了,而是字符串类型的。如果你们数据库对于金额的数据类型定义为数字的话,在存储到数据库之前是需要进行数据类型的转换的,而我们应该怎样设计才能达到,查看时是格式化的金额,而存储时是数字类型的呢?

此时我们就用到了ElementUI输入框中的两个事件,即:blur和focus,我们先来看一下ElementUI技术文档上的定义

elementui只能输入小数 elementui 数字输入框_elementui

 根据ElementUI的技术文档我们可以得知,当鼠标点击输入框时,会让输入框获得焦点从而触发事件,同理,当鼠标点击输入框之外的部分会让其失去焦点同样也触发事件。所以我们在设计时应该是blur事件触发时金额被格式化,focus事件触发时金额恢复原貌。



<template>
 <div>
  <el-input
      v-model.trim="totalprice"
      clearable
      maxlength="15" 
      placeholder="请输入金额"
      @focus="uninputMoney($event)"
      @blur="inputMoney($event)" >
     <template slot="append">元</template>
   </el-input>
</div>
</template>

<script>
  export default {
   name: "contractList", 
  data(){
   return {
   totalprice:null
}
},
   methods: {
// 失去焦点金额格式化
  inputMoney(el) {
      let temp = Number(el.target.value) || null;
      this.totalprice = this.priceFormat(temp)
    },
    // 获得焦点金额去掉格式
  uninputMoney(el) {
     if (!!el.target.value) {
       this.totalprice = this.delcommafy(el.target.value)
     }else {
       this.totalprice = null
     }
  },
priceFormat(num,n){  
   n = n || 2;
  let symbol = ",";
    if (num === null) return num;
    if(typeof num!=='number')throw new TypeError('num参数应该是一个number类型');
    if(n<0)throw new Error('参数n不应该小于0');
    let hasDot=parseInt(num)!=num;//这里检测num是否为小数,true表示小数
    let m = (n!=undefined&&n!=null)?n:1;
    num = m == 0?num.toFixed(m)+'.':hasDot?(n?num.toFixed(n):num):num.toFixed(m);
    symbol = symbol||',';
    num = num.toString().replace(/(\d)(?=(\d{3})+\.)/g,function(match, p1,p2) {
        return p1 + symbol;
    });
    if(n==0||(!hasDot&&!n)){//如果n为0或者传入的num是整数并且没有指定整数的保留位数,则去掉前面操作中的小数位
        num =  num.substring(0,num.indexOf('.'));
    }
    return num;
}

//去除千分位中的‘,’
delcommafy (num){
  if(!num) return num;
  num = num.toString();
  num = num.replace(/,/gi, '');
  if (num.indexOf('.00') >0) num = parseInt(num); 
  return num;
}
 }
} 
</script>



更新:

由于JS中的Number()函数最大只能处理到 2的53次方-1,即9,007,199,254,740,991。如果超过这个数,那字符串转化之后的数字精度会丢失,所以我们要限制输入框的位数为15位,保证不超出精度。

在delcommafy函数中增加了一段代码



if (num.indexOf('.00') >0) num = parseInt(num);



这段代码意思是当15位整数被格式化会在金额最后出现“ .00”,而当输入框又获得焦点时要删除掉最后的“.00”字符,这样在点击输入框后我们才能编辑这段金额。

JS里转化数字类型的函数有很多,整型parseInt() 、浮点数parseFloat还有大整数BigInt。这里额外说一下这个BigInt这个数据类型,它是任意精度和位数的整数,生成之后会在整数后方加一个n。

elementui只能输入小数 elementui 数字输入框_javascript_02

需要注意的是,这种数据类型是不同于字符串和普通数字类型,但它支持基本的四则运算法则,这样在处理一些金融业务或者超大的整数时我们有了一个非常可靠和实用的工具。