el-Input输入数字自动转千分位进行展示,存储值不变
子组件:
<template><el-input ref="inputRef" :disabled="disabled" clearable v-model="displayValue" v-bind="$attrs" @input="handleInput" @focus="handleFocus" @blur="handleBlur" @change="handleChange" @keydown="handleKeyDown" @compositionstart="handleCompositionStart" @compositionend="handleCompositionEnd"></el-input>
</template><script>
export default {name: 'AmountInput',props: {value: {type: [Number, String],default: null,},disabled: {type: Boolean,default: false,},precision: {type: Number,default: 2,},bigNumber: {type: Boolean,default: true,},},data() {return {displayValue: '',internalValue: null,isFocused: false,lastValidValue: null,isComposing: false, };},watch: {value: {immediate: true,handler(newVal) {const parsed = this.parseInputValue(newVal);if (parsed !== this.internalValue) {this.internalValue = parsed;this.formatDisplayValue();}},},},mounted() {this.internalValue = this.parseInputValue(this.value);this.formatDisplayValue();},methods: {safeToString(value) {if (value === null || value === undefined) return '';return String(value);},handleCompositionStart() {this.isComposing = true;},handleCompositionEnd(e) {this.isComposing = false;this.handleInput(e.target.value);},processBigNumber(numStr) {console.log(numStr, 'numStr');if (!numStr) return '';let cleaned = numStr.replace(/[^\d.-]/g, '');const isNegative = cleaned.startsWith('-');if (isNegative) cleaned = cleaned.substring(1);const parts = cleaned.split('.');let integerPart = parts[0].replace(/^0+/, '') || '0';let decimalPart = parts.length > 1 ? parts[1] : '';if (decimalPart.length > this.precision) {decimalPart = decimalPart.substring(0, this.precision);}integerPart = integerPart.replace(/\B(?=(\d{3})+(?!\d))/g, ',');return (isNegative ? '-' : '') + integerPart + (decimalPart ? `.${decimalPart}` : '');},formatDisplayValue() {if (this.isFocused) {this.displayValue = this.internalValue !== null ? this.safeToString(this.internalValue) : '';} else {this.displayValue = this.formatNumber(this.internalValue);}},parseInputValue(value) {if (value === '' || value === null || value === undefined) return null;const numStr = this.safeToString(value).replace(/,/g, '').replace(/[^\d.-]/g, '');if (numStr === '-' || numStr === '.') return null;if (numStr.length > 15) {return numStr; }const num = Number(numStr);return isNaN(num) ? null : num;},convertFromScientificNotation(num) {if (num === null || num === undefined) return null;if (typeof num === 'string' && num.includes('e')) {try {return Number(num).toString();} catch {return num;}}if (typeof num === 'number' && num.toString().includes('e')) {return num.toLocaleString('fullwide', { useGrouping: false });}return num.toString();},formatNumber(value) {if (value === null || value === undefined) return '';const numStr = this.safeToString(value);const isNegative = numStr.startsWith('-');const cleanStr = isNegative ? numStr.substring(1) : numStr;const parts = cleanStr.split('.');let integerPart = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ',');let decimalPart = parts.length > 1 ? parts[1].substring(0, this.precision) : '';return (isNegative ? '-' : '') + integerPart + (decimalPart ? `.${decimalPart}` : '');},validateInput(value) {if (value === '' || value === null) return true;return new RegExp(`^-?\\d*\\.?\\d{0,${this.precision}}$`).test(value);},handleInput(value) {if (this.isComposing) return; const strValue = this.safeToString(value);const filtered = strValue.replace(/[^\d.-]/g, '');const decimalParts = filtered.split('.');let cleanedValue = decimalParts[0];if (decimalParts.length > 1) {cleanedValue += '.' + decimalParts.slice(1).join('').substring(0, this.precision);}if (cleanedValue.includes('-')) {cleanedValue = '-' + cleanedValue.replace(/-/g, '');}if (cleanedValue !== this.displayValue) {this.displayValue = cleanedValue;}const parsed = this.parseInputValue(cleanedValue);this.internalValue = parsed;this.lastValidValue = cleanedValue;this.$emit('input', parsed);},handleFocus() {this.isFocused = true;this.formatDisplayValue();this.$emit('focus');},handleBlur() {this.isFocused = false;const parsed = this.parseInputValue(this.displayValue);this.internalValue = parsed;this.formatDisplayValue();this.$emit('blur');this.$emit('change', parsed);},handleKeyDown(e) {const allowedKeys = [8,9,37,39,46,35,36, ...(e.ctrlKey ? [65, 67, 86, 88] : []), ];if (/\d/.test(e.key) || allowedKeys.includes(e.keyCode) || (e.key === '.' && !this.displayValue.includes('.')) || (e.key === '-' && !this.displayValue.includes('-') && (this.displayValue === '' || e.target.selectionStart === 0))) return;e.preventDefault();},},
};
</script>
父组件
<currency-input :value="addFormData.advancePaymentAmt" big-number :precision="2" @input="handleAmountInput($event, 'advancePaymentAmt')"></currency-input>
function handleAmountInput(data: any, field: string, type?: string, cIndex?: number) {state.formData[field] = data;
}