基于Element的el-input实现一个可以显示千分位符的金额输入框

直接上代码

复制代码
1 <template>
2   <!-- 定义一个 Element UI 的输入框组件 -->
3   <el-input
4     v-model="formattedValue"
5     @input="handleInput"
6     @change="handleChange"
7   ></el-input>
8 </template>
复制代码
  1 <script>
  2 /**
  3  * MyFormattedInput 组件,用于格式化输入的数字,并添加千分位分隔符
  4  * 
  5  * @props {Number|String} value - 输入的值,默认为 0
  6  */
  7 export default {
  8   // 组件名称
  9   name: "MyFormattedInput",
 10   // 定义组件的 props
 11   props: {
 12     value: {
 13       // 支持的类型为数字或字符串
 14       type: [Number, String],
 15       // 默认值为 0
 16       default: 0,
 17     },
 18   },
 19   // 计算属性
 20   computed: {
 21     formattedValue: {
 22       /**
 23        * 获取格式化后的值
 24        * 
 25        * @returns {String} 格式化后的字符串,添加了千分位分隔符
 26        */
 27       get() {
 28         // 打印获取值时的日志
 29         console.log("get", this.value);
 30         // 将值转换为字符串,并添加千分位分隔符
 31         return this.value.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
 32       },
 33       /**
 34        * 设置格式化后的值,并触发 input 事件
 35        * 
 36        * @param {String} formattedValue - 格式化后的值
 37        */
 38       set(formattedValue) {
 39         // 打印设置值时的日志
 40         console.log("set", formattedValue);
 41         // 获取小数点的索引
 42         const pointIndex = formattedValue.indexOf(".");
 43         // 判断最后一个字符是否为小数点
 44         const hasLastPoint = formattedValue[formattedValue.length - 1] === ".";
 45         // 判断是否包含小数点
 46         const hasPoint = formattedValue.includes(".");
 47         if (hasPoint && hasLastPoint) {
 48           // 如果包含小数点且最后一个字符是小数点,移除逗号并触发 input 事件
 49           this.$emit("input", formattedValue.replace(/,/g, ""));
 50         } else if (hasPoint && !hasLastPoint) {
 51           if (formattedValue.length - 2 > pointIndex) {
 52             // 如果包含小数点且有足够的小数位数,移除逗号并保留两位小数
 53             this.$emit(
 54               "input",
 55               this.toFixedNoRound(parseFloat(formattedValue.replace(/,/g, "")), 2)
 56             );
 57           } else {
 58             // 如果小数位数不足,移除逗号并触发 input 事件
 59             this.$emit("input", formattedValue.replace(/,/g, ""));
 60           }
 61         } else {
 62           // 如果不包含小数点,移除逗号并转换为数字,若为 NaN 则为 0
 63           this.$emit(
 64             "input",
 65             parseFloat(formattedValue.replace(/,/g, "")) || 0
 66           );
 67         }
 68       },
 69     },
 70   },
 71   // 组件的方法
 72   methods: {
 73     /**
 74      * 处理输入事件
 75      * 
 76      * @param {String} value - 输入的值
 77      */
 78     handleInput(value) {
 79       // 打印输入事件的日志
 80       console.log("handleInput", value);
 81       // 计算小数点出现的次数
 82       var pointShowCount = value.split(".").length - 1;
 83       if (pointShowCount == 0 || pointShowCount == 1) {
 84         // 如果小数点出现 0 或 1 次
 85         if (isNaN(parseFloat(value.replace(/,/g, "")))) {
 86           // 如果移除逗号后不是数字,触发 input 事件并传入 0
 87           this.$emit("input", 0);
 88         }
 89       }
 90     },
 91     /**
 92      * 处理值改变事件
 93      * 
 94      * @param {String} value - 改变后的值
 95      */
 96     handleChange(value) {
 97       // 打印值改变事件的日志
 98       console.log("handleChange", value);
 99       if (isNaN(parseFloat(value.replace(/,/g, "")))) {
100         // 如果移除逗号后不是数字,触发 change 事件并传入 0
101         this.$emit("change", 0);
102       } else {
103         // 如果是数字,移除逗号并转换为数字,若为 NaN 则为 0
104         this.$emit("change", parseFloat(value.replace(/,/g, "")) || 0);
105       }
106     },
107     /**
108      * 截取指定小数位数,不进行四舍五入
109      * 
110      * @param {Number} num - 要处理的数字
111      * @param {Number} decimals - 保留的小数位数
112      * @returns {String} 处理后的字符串,保留指定小数位数
113      */
114     toFixedNoRound(num, decimals) {
115       // 计算乘数
116       const multiplier = Math.pow(10, decimals);
117       // 截取小数部分
118       const truncatedNum = Math.trunc(num * multiplier) / multiplier;
119       // 转换为字符串并保留指定小数位数
120       return truncatedNum.toFixed(decimals);
121     },
122   },
123 };
124 </script>
  • get() 方法:将 this.value 转换为字符串,并使用正则表达式 /\B(?=(\d{3})+(?!\d))/g 添加千分位分隔符。
  • set() 方法:根据输入值的不同情况处理小数点和小数位数,并触发 input 事件。
  • handleInput(value):处理输入事件,计算小数点出现的次数,若移除逗号后不是数字,则触发 input 事件并传入 0。
  • handleChange(value):处理值改变事件,若移除逗号后不是数字,则触发 change 事件并传入 0;否则,移除逗号并转换为数字,若为 NaN 则为 0。
  • toFixedNoRound(num, decimals):截取指定小数位数,不进行四舍五入。