1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104
| <template> <el-input v-model="localValue" @input="handleInput" :placeholder="placeholder" :clearable="clearable" /> </template>
<script> export default { name: 'NumberInput', props: { value: { type: [Number, String], default: null }, min: { type: Number, default: -Infinity }, max: { type: Number, default: Infinity }, /** * 小数点后保留的位数 */ precision: { type: Number, default: 0 }, /** * 是否允许输入负数 */ allowNegative: { type: Boolean, default: false }, placeholder: { type: String, default: '请输入数字' }, clearable: { type: Boolean, default: true } }, data() { return { localValue: this.value || '' } }, watch: { value(newValue) { if (newValue !== this.localValue) { this.localValue = newValue } }, localValue(newValue) { this.$emit('input', newValue) } }, methods: { handleInput() { let value = this.localValue
// 如果允许负数,先处理负号 const isNegative = value.startsWith('-') if (isNegative && !this.allowNegative) { value = value.replace('-', '') // 如果不允许负数,去掉负号 }
// 如果 precision 为 0,则禁止输入小数点 if (this.precision === 0) { value = value.replace(/\./g, '') // 禁止输入小数点 }
// 格式化为最多 `precision` 位小数 const decimalRegex = `^\\D*(\\d*(?:\\.\\d{0,${this.precision}})?).*` value = value.replace(new RegExp(decimalRegex), '$1')
// 如果之前是负数,重新加上负号 if (isNegative && this.allowNegative) { value = `-${value}` }
// 限制最大值和最小值 if (parseFloat(value) < this.min) { value = String(this.min) } else if (parseFloat(value) > this.max) { value = String(this.max) }
// 更新本地值 this.localValue = value } } } </script>
<style scoped> </style>
|