vue Element组件库<el-input>限制只能输入数字,且保留小数后两位
项目需求el-input组件输入的时候使用v-model.number="value"
一开始可以输入任何字符。除非第一次输入为数字,后面输入的内容才会被限制,只能输入数字。这个并不符合需求。
* 数字类型的验证需要在 v-model
处加上 .number
的修饰符,这是 Vue
自身提供的用于将绑定值转化为 number
类型的修饰符。(只能输入整数)
我们要实现如下功能:
- 必须为数字
- 只能有一个小数点
- 小数点后保留两位小数
- 当第一位输入小数点的时候自动补全,补为 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 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>
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: {
/**
* @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>
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 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>
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: { 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>