新建PriceInput.vue
<template><div id="bord"><el-inputv-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 = nreturn}if (this.inputing) {this.inputValue = n} else {this.inputValue = formatMoney(inputNumber(n.toString()), this.format)}}}},methods: {handleInput (val) {this.inputing = truelet money = inputNumber(val)const format = this.formatconst 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 = moneylet value = ''if (money === '-' || money === '.') {value = ''} else if (money !== '') {value = Number(inputNumber(money))}this.$emit('input', value)},handleChange (val) {this.inputing = truethis.$emit('change', Number(val.replaceAll(',', '')))},handleBlur (e) {this.inputing = falsethis.inputValue = formatMoney(inputNumber(e.target.value), this.format)this.$emit('blur', e)},handleFocus (e) {this.inputing = truethis.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 moneyif (!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 valif (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|\-|\.]/gconst reg2 = /(\d|\.)\-+/gconst str = val.replace(reg1, '').replace(reg2, '$1')const pointArr = str.split('.')let value = ''if (pointArr.length > 1) {pointArr.forEach((item, index) => {value = value + itemif (!index) {value = value + '.'}})} else {value = str}return value
}
使用案例
<PriceInputv-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);}}}