<template>
<el-input
:value="value"
:placeholder="placeholder"
@input="handleInput"
@focus="handleFocus"
@blur="handleBlur"
>
<template slot="prepend">
<slot name="prepend" />
</template>
<template slot="append">
<slot name="append" />
</template>
<template slot="prefix">
<slot name="prefix" />
</template>
<template slot="suffix">
<slot name="suffix" />
</template>
</el-input>
</template>
<script>
export default {
name: 'NumberFormatInput',
components: {},
props: {
placeholder: {
type: String,
default: '请输入'
},
value: {
type: String,
default: ''
},
decimal: {
// 保留小数位数
type: Number,
default: 2
}
},
emits: ['on-change'],
data() {
return {
input: ''
}
},
computed: {
decimalNum() {
return Math.pow(10, this.decimal)
}
},
watch: {},
created() {},
beforeMount() {},
mounted() {},
methods: {
handleInput(value) {
value = value.replace(/[^\d.-]/g, '') // 可以为负数
value = value.replace(/^\./g, '') // 验证第一个字符是数字而不是.
value = value.replace(/\.{2,}/g, '.') // 只保留第一个. 清除多余的
value = value.replace(/^(-)|-+/g, '$1') // - 只能在第一位
value = value.replace('.', '$#$').replace(/\./g, '').replace('$#$', '.') // 保证.只出现一次,而不能出现两次以上
this.$emit('input', value)
},
// 数值三位以,隔开
format_number(n) {
var b = parseInt(n).toString()
var len = b.length
if (len <= 3) {
return b
}
var r = len % 3
return r > 0
? b.slice(0, r) + ',' + b.slice(r, len).match(/\d{3}/g).join(',')
: b.slice(r, len).match(/\d{3}/g).join(',')
},
handleFocus(e) {
if (!e.target.value) return
this.handleInput(e.target.value)
},
handleBlur(e) {
if (!e.target.value) {
this.$emit('input', '')
this.$emit('on-change')
return
}
let value = e.target.value
value = String(Math.round(value * this.decimalNum) / this.decimalNum)
let first = ''
if (value[0] === '-') {
first = '-'
value = value.slice(1)
}
const left = this.format_number(value.split('.')[0])
// const right = value.split('.')[1] || '0'.repeat(this.decimal) // 整数自动补0
const right = value.split('.')[1] || ''
// value = left + '.' + right // 自动补0可以一直有小数点
value = first + left + (right ? '.' : '') + right // 整数不要小数点
this.$emit('input', value)
this.$emit('on-change')
}
}
}
</script>
<style lang="scss" scoped></style>
