|
|
|
@ -1,5 +1,6 @@ |
|
|
|
<template> |
|
|
|
<el-input v-bind="$attrs" v-model="internalValue" @input="handleInput" @blur="handleBlur" :placeholder="placeholder" :disabled="disabled" type="text" > |
|
|
|
<el-input v-bind="$attrs" v-model="internalValue" @input="handleInput" @blur="handleBlur" :placeholder="placeholder" |
|
|
|
:disabled="disabled" type="text"> |
|
|
|
|
|
|
|
<template slot="prepend" v-if="prepend"> |
|
|
|
{{ prepend }} |
|
|
|
@ -40,6 +41,7 @@ export default { |
|
|
|
watch: { |
|
|
|
value(newVal) { |
|
|
|
// 外部值变化时同步到内部(但不做格式化,避免干扰用户输入) |
|
|
|
console.log(newVal,"newVal") |
|
|
|
if (newVal === '' || newVal == null) { |
|
|
|
this.internalValue = ''; |
|
|
|
} else { |
|
|
|
@ -49,85 +51,72 @@ export default { |
|
|
|
}, |
|
|
|
methods: { |
|
|
|
handleInput(val) { |
|
|
|
console.log(val,"val") |
|
|
|
if (val === '') { |
|
|
|
this.internalValue = ''; |
|
|
|
this.$emit('input', ''); |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
// 1. 清除非合法字符(只保留数字、小数点、开头的负号) |
|
|
|
// 1. 只保留数字、小数点、开头的负号 |
|
|
|
let cleaned = val |
|
|
|
.replace(/[^\d.-]/g, '') |
|
|
|
.replace(/^(-)\1+/, '$1'); // 只允许一个开头的负号 |
|
|
|
.replace(/^(-)\1+/, '$1'); // 合并多个负号 |
|
|
|
|
|
|
|
// 2. 处理多个小数点:只保留第一个 |
|
|
|
const dotIndex = cleaned.indexOf('.'); |
|
|
|
if (dotIndex !== -1) { |
|
|
|
const beforeDot = cleaned.slice(0, dotIndex); |
|
|
|
const afterDot = cleaned.slice(dotIndex + 1).replace(/\./g, ''); // 移除后面所有小数点 |
|
|
|
cleaned = beforeDot + '.' + afterDot; |
|
|
|
// 2. 只保留第一个小数点 |
|
|
|
const firstDotIndex = cleaned.indexOf('.'); |
|
|
|
if (firstDotIndex !== -1) { |
|
|
|
const before = cleaned.slice(0, firstDotIndex); |
|
|
|
const after = cleaned.slice(firstDotIndex + 1).replace(/\./g, ''); |
|
|
|
cleaned = before + '.' + after; |
|
|
|
} |
|
|
|
|
|
|
|
// 3. 限制小数位数(仅当有小数点时) |
|
|
|
// 3. 限制小数位数(仅当允许小数时) |
|
|
|
if (this.decimalDigits > 0 && cleaned.includes('.')) { |
|
|
|
const parts = cleaned.split('.'); |
|
|
|
let integerPart = parts[0]; |
|
|
|
let decimalPart = parts[1] || ''; |
|
|
|
|
|
|
|
// 限制小数位长度 |
|
|
|
if (decimalPart.length > this.decimalDigits) { |
|
|
|
decimalPart = decimalPart.slice(0, this.decimalDigits); |
|
|
|
} |
|
|
|
|
|
|
|
// 关键修复:即使 decimalPart 为空(如 "1."),也要保留小数点! |
|
|
|
cleaned = integerPart + '.' + decimalPart; |
|
|
|
const [intPart, decPart = ''] = cleaned.split('.'); |
|
|
|
cleaned = intPart + '.' + decPart.slice(0, this.decimalDigits); |
|
|
|
} else if (this.decimalDigits === 0) { |
|
|
|
// 不允许小数,移除小数点及之后内容 |
|
|
|
cleaned = cleaned.split('.')[0]; |
|
|
|
cleaned = cleaned.split('.')[0]; // 移除小数部分 |
|
|
|
} |
|
|
|
|
|
|
|
// 4. 处理以 . 或 -. 开头的情况 |
|
|
|
if (cleaned === '.') { |
|
|
|
cleaned = '0.'; |
|
|
|
} else if (cleaned === '-.') { |
|
|
|
cleaned = '-0.'; |
|
|
|
} else if (cleaned.startsWith('.')) { |
|
|
|
cleaned = '0' + cleaned; |
|
|
|
} else if (cleaned.startsWith('-.')) { |
|
|
|
cleaned = '-0.' + cleaned.slice(2); |
|
|
|
} |
|
|
|
// 4. 处理以 . 或 -. 开头 |
|
|
|
if (cleaned === '.') cleaned = '0.'; |
|
|
|
else if (cleaned === '-.') cleaned = '-0.'; |
|
|
|
else if (cleaned.startsWith('.')) cleaned = '0' + cleaned; |
|
|
|
else if (cleaned.startsWith('-.')) cleaned = '-0.' + cleaned.slice(2); |
|
|
|
|
|
|
|
// 5. 去掉整数部分的前导零(但保留单个 0 或负数中的 -0) |
|
|
|
// 5. 【关键】安全去除前导零,但保留单个 0 |
|
|
|
if (cleaned.includes('.')) { |
|
|
|
// 有小数点时,整数部分可以是 0 或 -0 |
|
|
|
const parts = cleaned.split('.'); |
|
|
|
let intPart = parts[0]; |
|
|
|
if (intPart === '' || intPart === '-') { |
|
|
|
intPart = intPart + '0'; |
|
|
|
} else if (/^-?0+\d/.test(intPart)) { |
|
|
|
// 如 -0012 → -12,0012 → 12 |
|
|
|
intPart = intPart.replace(/^-?0+(\d)/, '$1'); |
|
|
|
// 有小数点:处理整数部分 |
|
|
|
const [int, dec] = cleaned.split('.'); |
|
|
|
// 整数部分:-0012 → -12,00 → 0,0 → 0,-0 → 0(或保留 -0) |
|
|
|
let newInt = int; |
|
|
|
if (/^-?0+\d/.test(int)) { |
|
|
|
newInt = int.replace(/^-?0+(\d)/, '$1'); |
|
|
|
} else if (int === '' || int === '-') { |
|
|
|
newInt = int + '0'; |
|
|
|
} else if (int === '00' || /^-00+$/.test(int)) { |
|
|
|
newInt = int.startsWith('-') ? '-0' : '0'; |
|
|
|
} |
|
|
|
cleaned = intPart + '.' + parts[1]; |
|
|
|
cleaned = newInt + '.' + dec; |
|
|
|
} else { |
|
|
|
// 无小数点 |
|
|
|
if (/^-?0+\d/.test(cleaned)) { |
|
|
|
cleaned = cleaned.replace(/^-?0+(\d)/, '$1'); |
|
|
|
} else if (cleaned === '00' || /^-00+$/.test(cleaned)) { |
|
|
|
cleaned = cleaned.startsWith('-') ? '-0' : '0'; |
|
|
|
} |
|
|
|
// 注意:不要把单独的 '0' 变成 '' |
|
|
|
} |
|
|
|
|
|
|
|
this.internalValue = cleaned; |
|
|
|
|
|
|
|
// emit 值(可能是数字、空字符串、或 '-') |
|
|
|
// emit |
|
|
|
if (cleaned === '' || cleaned === '-') { |
|
|
|
this.$emit('input', cleaned === '-' ? '-' : ''); |
|
|
|
} else { |
|
|
|
const num = parseFloat(cleaned); |
|
|
|
if (!isNaN(num)) { |
|
|
|
this.$emit('input', num); |
|
|
|
} else { |
|
|
|
this.$emit('input', ''); |
|
|
|
} |
|
|
|
console.log(num,isNaN(num),"num") |
|
|
|
this.$emit('input', isNaN(num) ? '' : num); |
|
|
|
} |
|
|
|
}, |
|
|
|
|
|
|
|
|