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>