后臺開發(fā)常遇到只能輸入整數(shù)、x位小數(shù)光涂,有些ui庫有寫好的組件庞萍,有些ui庫又沒有,索性封裝一下
原因:
- 使用type="number"的輸入框忘闻,框內(nèi)會有2個小箭頭钝计,產(chǎn)品不想看到2個小箭頭
- 項目使用的ui庫輸入框組件沒有控制精度的字段,且數(shù)字輸入框組件不符合要求
- 通過監(jiān)聽事件把輸入值parseInt/parseFloat/toFixed,在交互上讓人感覺很突兀
需求:
- 正常輸入私恬,不通過失去焦點或防抖那種改變輸入的值交播,要在輸入時就限制
- 可以輸入正/負整數(shù)、正/負浮點數(shù)
- 數(shù)值精度可以自己控制
- 可已控制最大和最小輸入的值
- 多位整數(shù)開頭不能為0践付,浮點數(shù)多整數(shù)位開頭不能為0秦士,正浮點數(shù)小于1/負浮點數(shù)大于-1整數(shù)位0不能重復(fù)
- 開頭不能是.號
使用:
// 使用element的input組件
<el-input @input="onInput" v-model="input" placeholder="請輸入內(nèi)容"></el-input>
完整版
// methods
onInput(val) {
this.input = this.handleInput(val, 2, 100, -500); // 完整版
// this.input = this.handleInput_1(val, 2, 100, 0); // 正數(shù)
// this.input = this.handleInput_1(val, 0, 100, 0); // 正數(shù)
// this.input = this.handleInput_2(val, 100, 0); // 正整數(shù)
// this.input = this.handleInput_3(val, 2, 100, 0); // 正浮點數(shù)
// this.input = this.handleInput_4(val, 0, 100, -500); // 負數(shù)
// this.input = this.handleInput_5(val, 100, -500); // 負整數(shù)
// this.input = this.handleInput_6(val, 2, 100, -500); // 負浮點數(shù)
},
handleInput(val, precision = 0, max, min) {
// 用構(gòu)造函數(shù)創(chuàng)建,是方便使用字符模板永高,而\\轉(zhuǎn)義符號隧土,是因為構(gòu)造函數(shù)創(chuàng)建正則,字符串會轉(zhuǎn)義一次而正則又會轉(zhuǎn)義一次
const regexp = new RegExp(`^(-)*(\\d+)\\.(\\d{0,${precision}}).*$`);
let str = String(val);
str = str.replace(/^[^-\d]/, ""); // 保證負號和數(shù)字開頭
if (str.search(/^-/) > -1) { // 負數(shù)
if (precision > 0) { // 負浮點數(shù)
str = str
.replace(/[^-\d\.]/g, "") // 負浮點數(shù)只能輸入3種字符: -號 .號 數(shù)字
.replace("-", "減號") // 標識第一個-號 沒用正則只會匹配一個 隨便怎么標識 用'傻逼'都行
.replace(/-/g, "") // 正則匹配-并刪除 第一個-號被標識成了'減號'所以被保留
.replace(/減號\./, "減號") // 保證標識的-號后面是數(shù)字 如果是.號就刪除
.replace(".", "點號") // 標識第一個正確輸入的.號
.replace(/\./g, "") // 刪除多余的.號
.replace("減號", "-") // 將標識轉(zhuǎn)為正確的字符
.replace("點號", ".") // 同上
.replace(regexp, "$1$2.$3") // 完成 - 匹配正確的數(shù)字($1命爬、$2曹傀、$3...是使用正則組匹配,忘了去翻資料)
.replace(/^-(0+)(\d+)(\..)?/, "-$2$3") // 拓展 - 小于-1的浮點數(shù)開頭不能為0
.replace(/^-(0+)(\..)?/, "-0$2"); // 拓展 - 大于-1的浮點數(shù)0不能重復(fù)
} else { // 負整數(shù)
str = str
.replace(/[^-\d]/g, "") // 負整數(shù)只能輸入2種字符: -號 數(shù)字
.replace("-", "減號")
.replace(/-/g, "")
.replace(/減號\./, "減號")
.replace("減號", "-")
.replace(/^-(0+)(\d+)/, "-$2"); // 多位整數(shù)開頭不能為0
}
} else { // 正數(shù)
if (precision > 0) { // 正浮點數(shù)
str = str
.replace(/[^\d\.]/g, "") // 正浮點數(shù)只能輸入2種字符: .號 數(shù)字
.replace(".", "點號")
.replace(/\./g, "")
.replace("點號", ".")
.replace(regexp, "$1$2.$3")
.replace(/^(0+)(\d+)/, "$2"); // 小于1的浮點數(shù)開頭0不能重復(fù)
} else { // 正整數(shù)
str = str
.replace(/[^\d]/g, "") // 正整數(shù)只能輸入1種字符: 數(shù)字
.replace(/^(0+)(\d+)/, "$2"); // 多位整數(shù)開頭不能為0
}
}
if (min > str || str > max) str = ""; // 控制最終結(jié)果的在傳入的范圍內(nèi)
return str;
}
正數(shù)
handleInput_1(val, precision = 0, max, min) {
const regexp = new RegExp(`^(\\d+)\\.(\\d{0,${precision}}).*$`);
let str = String(val);
if (precision > 0) {
str = str
.replace(/^[^\d]/g, "") // 保證數(shù)字開頭
.replace(/[^\d\.]/g, "")
.replace(".", "點號")
.replace(/\./g, "")
.replace("點號", ".")
.replace(regexp, "$1.$2")
.replace(/^(0+)(\d+)/, "$2");
} else {
str = str
.replace(/[^\d]/g, "")
.replace(/^(0+)(\d+)/, "$2");
}
if (min > str || str > max) str = "";
return str;
}
正整數(shù)
handleInput_2(val, max, min) {
let str = String(val);
str = str
.replace(/[^\d]/g, "") // 所有正整數(shù)
.replace(/^(0+)(\d+)/, "$2");
// str.replace(/[^1-9]]/g, "") // 大于0的正整數(shù)
if (min > str || str > max) str = "";
return str;
}
正浮點數(shù)
handleInput_3(val, precision = 2, max, min) { // 一般是保留2位
const regexp = new RegExp(`^(\\d+)\\.(\\d{0,${precision}}).*$`);
let str = String(val);
str = str
.replace(/^[^\d]/g, "")
.replace(/[^\d\.]/g, "")
.replace(".", "點號")
.replace(/\./g, "")
.replace("點號", ".")
.replace(regexp, "$1.$2")
.replace(/^(0+)(\d+)/, "$2");
if (min > str || str > max) str = "";
return str;
}
負數(shù)
handleInput_4(val, precision = 0, max, min) {
const regexp = new RegExp(`^(-)(\\d+)\\.(\\d{0,${precision}}).*$`);
let str = String(val);
str = str.replace(/^[^-]/, "");
if (precision > 0) {
str = str
.replace(/[^-\d\.]/g, "")
.replace("-", "減號")
.replace(/-/g, "")
.replace(/減號\./, "減號")
.replace(".", "點號")
.replace(/\./g, "")
.replace("減號", "-")
.replace("點號", ".")
.replace(regexp, "$1$2.$3")
.replace(/^-(0+)(\d+)(\..)?/, "-$2$3")
.replace(/^-(0+)(\..)?/, "-0$2");
} else {
str = str
.replace(/[^-\d]/g, "")
.replace("-", "減號")
.replace(/-/g, "")
.replace(/減號\./, "減號")
.replace("減號", "-")
.replace(/^-(0+)(\d+)/, "-$2");
}
if (min > str || str > max) str = "";
return str;
}
負整數(shù)
handleInput_5(val, max, min) {
let str = String(val);
str = str
.replace(/^[^-]/, "")
.replace(/[^-\d]/g, "")
.replace("-", "減號")
.replace(/-/g, "")
.replace(/減號\./, "減號")
.replace("減號", "-")
.replace(/^-(0+)(\d+)/, "-$2");
if (min > str || str > max) str = "";
return str;
}
負浮點數(shù)
handleInput_6(val, precision = 2, max, min) { // 一般是保留2位
const regexp = new RegExp(`^(-)(\\d+)\\.(\\d{0,${precision}}).*$`);
let str = String(val);
str = str
.replace(/^[^-]/, "")
.replace(/[^-\d\.]/g, "")
.replace("-", "減號")
.replace(/-/g, "")
.replace(/減號\./, "減號")
.replace(".", "點號")
.replace(/\./g, "")
.replace("減號", "-")
.replace("點號", ".")
.replace(regexp, "$1$2.$3")
.replace(/^-(0+)(\d+)(\..)?/, "-$2$3")
.replace(/^-(0+)(\..)?/, "-0$2");
if (min > str || str > max) str = "";
return str;
}
問題:
- 負數(shù)只輸入-的情況
- 浮點數(shù)點可能會有xxx.的情況