基于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):截取指定小数位数,不进行四舍五入。

浙公网安备 33010602011771号