问题
- js精度问题
- 数字输入框校验有缺陷
- 数字输入框无法限制最大输入长度
方案
用字符串输入代替数字输入框
prototypeMethodExpansion.js
/**
* 数字字符串四舍五入保留位数(解决精度问题)
* @returns {string}
*/
String.prototype.ToFixed = function (d) {
var s = this + '';
s = s.replace(/[^-0-9.]/g, '');
if (!d) d = 0;
if (s.indexOf('.') == -1) s += '.';
s += new Array(d + 1).join('0');
if (new RegExp('^(-|\\+)?(\\d+(\\.\\d{0,' + (d + 1) + '})?)\\d*$').test(s)) {
var s1 = '0' + RegExp.$2,
pm = RegExp.$1,
a = RegExp.$3.length,
b = true;
if (a == d + 2) {
a = s1.match(/\d/g);
if (parseInt(a[a.length - 1]) > 4) {
for (var i = a.length - 2; i >= 0; i--) {
a[i] = parseInt(a[i]) + 1;
if (a[i] == 10) {
a[i] = 0;
b = i != 1;
} else break;
}
}
s1 = a
.join('')
.replace(new RegExp('(\\d+)(\\d{' + d + '})\\d$'), '$1.$2');
}
if (b) s1 = s1.substr(1);
return (pm + s1).replace(/\.$/, '');
}
return this + '';
};
/**
* 字符串转成合格数字字符串,允许限制正负数、小数点和最大输入长度
* allowNegative:允许负数
* allowDecimal:允许小数点
* maxLength:最大长度
* @returns {string}
*/
String.prototype.ToNumberString = function (options = {}) {
const {
allowNegative = false,
allowDecimal = true,
maxLength = Number.MAX_SAFE_INTEGER
} = options;
// 初始化结果字符串
let result = '';
let hasDecimalPoint = false;
let digitCount = 0; // 计算数字字符数量
let input = this.trim();
// 遍历输入字符串中的每个字符
for (let i = 0; i < input.length && digitCount < maxLength; i++) {
const char = input[i];
if (char === '.') {
if (!allowDecimal || hasDecimalPoint) break;
}
if (
(allowNegative && char === '-' && result === '') ||
(allowDecimal && char === '.' && !hasDecimalPoint) ||
('0' <= char && char <= '9')
) {
// 添加合法字符到结果字符串
result += char;
// 如果是数字字符,增加计数
if ('0' <= char && char <= '9') {
digitCount++;
}
// 如果当前字符是小数点,标记已存在小数点
if (char === '.') {
hasDecimalPoint = true;
}
}
}
return result;
};
/**
* 数字字符串移除后面多余的0
* @returns {string}
*/
String.prototype.RemoveExtra0 = function () {
return this.replace(/(?:(\.\d*[1-9])0+|\.0*)$/, '$1');
};
use
<el-input
v-model="formModel.draft"
@input="
formModel.draft = formModel.draft.ToNumberString({
allowNegative: false,
maxLength: 10,
})
"
@blur="
formModel.draft = String(formModel.draft || '')
.ToFixed(2)
.RemoveExtra0()
"
/>