新建PriceInput.vue
<template>
<div id="bord">
<el-input
v-model="inputValue"
v-bind="$attrs"
:maxlength="maxlength"
@input="handleInput"
@focus="handleFocus"
@blur="handleBlur"
@change="handleChange"
>
<template slot="append">
<slot name="append"></slot>
</template>
</el-input>
</div>
</template>
<script>
import { inputNumber } from '@/utils/inputNumber'
import { formatMoney } from '@/utils/formatMoney'
export default {
// name:'priceInput',
props: {
value: {
type: [String, Number],
default: ''
},
// 金额位数格式(a-b);a:整数位数;b:小数位数
format: {
type: String,
default: '9-2'
}
},
data () {
return {
inputValue: '',
inputing: false
}
},
computed: {
integerNum () {
return Number(this.format.split('-')[0])
},
decimalNum () {
return Number(this.format.split('-')[1])
},
maxlength () {
return this.integerNum + (this.decimalNum > 0 ? this.decimalNum + 1 : this.decimalNum)
}
},
watch: {
value: {
immediate: true,
handler (n) {
if (!n) {
this.inputValue = n
return
}
if (this.inputing) {
this.inputValue = n
} else {
this.inputValue = formatMoney(inputNumber(n.toString()), this.format)
}
}
}
},
methods: {
handleInput (val) {
this.inputing = true
let money = inputNumber(val)
const format = this.format
const intNum = Number(format.split('-')[0])
const decimalNum = Number(format.split('-')[1])
const moneyArr = money.split('.')
moneyArr[0] = moneyArr[0].length > intNum ? moneyArr[0].substr(0, intNum) : moneyArr[0]
if (moneyArr[1]) {
moneyArr[1] = moneyArr[1].length > decimalNum ? moneyArr[1].substr(0, decimalNum) : moneyArr[1]
}
money = moneyArr.join('.')
this.inputValue = money
let value = ''
if (money === '-' || money === '.') {
value = ''
} else if (money !== '') {
value = Number(inputNumber(money))
}
this.$emit('input', value)
},
handleChange (val) {
this.inputing = true
this.$emit('change', Number(val.replaceAll(',', '')))
},
handleBlur (e) {
this.inputing = false
this.inputValue = formatMoney(inputNumber(e.target.value), this.format)
this.$emit('blur', e)
},
handleFocus (e) {
this.inputing = true
this.inputValue = inputNumber(this.inputValue)
this.$emit('focus', e)
}
}
}
</script>
<style>
#bord>.el-input>input{
border: 0;
outline: none;/* 清除边框 */
text-align: right;
font-size: 18px;
background-color:transparent;/* 输入透明背景 */
}
</style>
formatMoney.js格式化金额
/**
* 格式化金额
* @param money { String / Number } 金额
* @param format { String } a-b:限制输入的字符长度,a:整数长度,b:小数长度
* @returns {string|null}
*/
export const formatMoney = (money, format) => {
if (typeof money === 'number') {
money = money.toString()
}
if (money === '-' || !money) return money
if (!format) format = '11-2'
const intNum = Number(format.split('-')[0])
const decimalNum = Number(format.split('-')[1])
const moneyArr = money.split('.')
moneyArr[0] = moneyArr[0].length > intNum ? moneyArr[0].substr(0, intNum) : moneyArr[0]
if (moneyArr[1]) {
moneyArr[1] = moneyArr[1].length > decimalNum ? moneyArr[1].substr(0, decimalNum) : moneyArr[1]
}
money = moneyArr.join('.')
const isNegativeNum = money.startsWith('-')
const pointPosition = money.indexOf('.')
const decimal = pointPosition !== -1 ? money.substr(pointPosition) : ''
const integer = Math.abs(parseInt(money).toString()).toString()
const integerArrReverse = integer.split('').reverse().join('')
const moneyStringify = `${isNegativeNum ? '-' : ''}${integerArrReverse.replace(/(\d{3})(?=\d)/g, '$1,').split('').reverse().join('')}${decimal}`
return moneyStringify
}
inputNumber.js格式化为普通数字格式
// 此方法用来实现将一个字符串通过replace方法,格式化为普通数字格式(包括正负整数、正负浮点数都支持)
export const inputNumber = val => {
if (val === '-' || !val) return val
if (val === '.') return ''
// 下列代码中正则表达式的非捕获组(?<=)在IE浏览器中不支持,所以弃用
// const reg1 = /[^\d|^\-|\^.]/g // 匹配所有非数字,非-,非.的字符
// const reg2 = /(?<=[\.|\-])[^\d]/g // 匹配所有.和-字符后的非数字字符
// const reg3 = /(?<=\.\d*)\./g // 匹配小数后的.
// const reg4 = /(?<=\d)\-/g // 匹配-后面的非数字
// return val.replace(reg1, '').replace(reg2, '').replace(reg3, '').replace(reg4, '')
const reg1 = /[^\d|\-|\.]/g
const reg2 = /(\d|\.)\-+/g
const str = val.replace(reg1, '').replace(reg2, '$1')
const pointArr = str.split('.')
let value = ''
if (pointArr.length > 1) {
pointArr.forEach((item, index) => {
value = value + item
if (!index) {
value = value + '.'
}
})
} else {
value = str
}
return value
}
使用案例
<PriceInput
v-model="yourModel"
:format="yourFormat"
@input="yourInputHandler"
@change="yourChangeHandler"
@blur="yourBlurHandler"
@focus="yourFocusHandler"
/>
export default {
data() {
return {
yourModel: '', // 初始化你的模型值
yourFormat: '11-2' // 初始化你的格式
};
},
methods: {
yourInputHandler(value) {
console.log('Input:', value);
},
yourChangeHandler(newValue) {
console.log('Changed:', newValue);
},
yourBlurHandler(event) {
console.log('Blurred:', event);
},
yourFocusHandler(event) {
console.log('Focused:', event);
}
}
}