vue element組件庫<el-input>限制只能輸入數字,且保留小數后兩位
項目需求el-input組件輸入的時候使用v-model.number="value"
一開始可以輸入任何字符。除非第一次輸入為數字,后面輸入的內容才會被限制,只能輸入數字。這個并不符合需求。
我們要實現如下功能:
- 必須為數字
- 只能有一個小數點
- 小數點后保留兩位小數
- 當第一位輸入小數點的時候自動補全,補為 0.
- 除非是小數,否則數字不能以0開頭
最終考慮通過綁定input
事件對輸入的內容進行自定義過濾,可以使用多種方式進行匹配,這里我舉兩種方式:
- 第一種為字符串切割匹配
- 第二種完全使用正則匹配
1. typescript字符串切割匹配版本
<template>
<div class="about">
<el-input placeholder="市場價" @input="limitInput($event,'mkPrice')" v-model.trim="form.mkPrice" />
<el-input placeholder="零售價" @input="limitInput($event,'slPrice')" v-model.trim="form.slPrice" />
</div>
</template>
<script lang="ts">
import { Component, Vue } from "vue-property-decorator";
@Component
export default class About extends Vue {
/**
* 自有屬性,定義后會在生成在construct構造器內容
*/
form: any = {
mkPrice: 0,
slPrice: 0,
};
/**
* methods
*/
// ts版本
limitInput(value: string, name: string) {
let str = (value && value.split("")) || [];
let reg1 = /\d/;
let reg2 = /\./;
// 第一個字符不能為小數點
if (str[0] == ".") {
this.form[name] = "";
return;
}
// 過濾掉除數字和小數點外的字符
value = str.filter((e: string) => reg1.test(e) || reg2.test(e));
// 匹配小數點后只能有兩位小數
let valJoin: any = value.join("");
this.form[name] = valJoin.match(/^\d*(\.?\d{0,2})/g)[0] || null;
}
}
</script>
2. JavaScript字符串切割匹配版本
<template>
<div class="about">
<el-input placeholder="市場價" @input="limitInput($event,'mkPrice')" v-model.trim="form.mkPrice" />
<el-input placeholder="零售價" @input="limitInput($event,'slPrice')" v-model.trim="form.slPrice" />
</div>
</template>
<script>
export default {
data() {
return {
form: {
mkPrice: "",
slPrice: "",
},
};
},
methods: {
limitInput(value, name) {
let val = (value && value.split("")) || [];
let reg1 = /\d/;
let reg2 = /\./;
// 第一個字符不能為小數點
if (val[0] == ".") {
this.form[name] = "";
return;
}
// 過濾掉除數字和小數點外的字符
val = str.filter((e) => reg1.test(e) || reg2.test(e));
// 匹配小數點后只能有兩位小數
// 解釋一下這個match正則規格
// ^\d* 是指以數字開頭,后面允許輸入0到多位數字
// (\.?) 是指只允許一個小數點
// \d{0,2} 是指只允許0到2位小數
this.form[name] = val.join("").match(/^\d*(\.?\d{0,2})/g)[0] || null;
},
},
};
</script>
3. typescript正則匹配版本
<template>
<div class="about">
<el-input placeholder="市場價" @input="limitInput($event,'mkPrice')" v-model.trim="form.mkPrice" />
<el-input placeholder="零售價" @input="limitInput($event,'slPrice')" v-model.trim="form.slPrice" />
</div>
</template>
<script lang="ts">
import { Component, Vue } from "vue-property-decorator";
@Component
export default class About extends Vue {
/**
* 自有屬性,定義后會在生成在construct構造器內容
*/
form: any = {
mkPrice: 0,
slPrice: 0,
};
/**
* methods
*/
// ts版本
limitInput(value: string, name: string) {
let val: any = "" + value;
val =
val
.replace(/[^\d^\.]+/g, "")
.replace(/^0+(\d)/, "$1")
.replace(/^\./, "0.")
.match(/^\d*(\.?\d{0,2})/g)[0] || "";
this.form[name] = val
}
}
</script>
4. javascript 正則匹配版本
<template>
<div class="about">
<el-input placeholder="市場價" @input="limitInput($event,'mkPrice')" v-model.trim="form.mkPrice" />
<el-input placeholder="零售價" @input="limitInput($event,'slPrice')" v-model.trim="form.slPrice" />
</div>
</template>
<script>
export default {
data() {
return {
form: {
mkPrice: "",
slPrice: "",
},
};
},
methods: {
/**
* @param {string} value - 輸入的值
* @param {string} name - 匹配的對象屬性 [mkPrice | slPrice]
*/
limitInput(value, name) {
this.form[name] =
("" + value) // 第一步:轉成字符串
.replace(/[^\d^\.]+/g, "") // 第二步:把不是數字,不是小數點的過濾掉
.replace(/^0+(\d)/, "$1") // 第三步:第一位0開頭,0后面為數字,則過濾掉,取后面的數字
.replace(/^\./, "0.") // 第四步:如果輸入的第一位為小數點,則替換成 0. 實現自動補全
.match(/^\d*(\.?\d{0,2})/g)[0] || ""; // 第五步:最終匹配得到結果 以數字開頭,只有一個小數點,而且小數點后面只能有0到2位小數
},
},
};
</script>