背景:
在日常项目开发过程中,我们经常会用到 ElementUI
这个组件库,其中的 el-input
组件很好用,但是没有对填写内容进行限制的功能,特别是有的项目中需要限制只能填写数字,不能为负数,不能有多个小数点,小数位多少,整数位多少等等。这些需求下,组件默认的功能就很难满足了,需要专门写代码来控制。
为了减少开发成本,提高工作效率,我整理了如下2种方法,大家可以根据实际情况使用,以下方法仍旧适用普通 input
标签。
方法一
使用行内正则控制。
oninput ="value=value.replace(/[^\d]/g, '')" // 只能输入数字(正整数)
oninput ="value=value.replace(/[^\-\d]/g, '')" // 只能输入数字(包含正负数)
oninput ="value=value.replace(/[^\-\d.]/g, '')" // 只能输入数字和小数
oninput ="value=value.replace(/[^\d.]/g, '').replace(/^(\d+)\.(\d\d).*$/, '$1.$2')" // 只能输入数字和小数,只保留一个小数点
oninput ="value=value.replace(/[^\-\d.]/g, '').replace(/^(\-)*(\d+)\.(\d+).*$/, '$1$2.$3')" // 只能输入数字和小数,只保留一个小数点(包含负数)
oninput ="value=value.replace(/[^\-\d.]/g, '').replace(/^(\-)*(\d+)\.(\d\d).*$/, '$1$2.$3')" // 只能输入数字和小数,只保留一个小数点,只保留2位小数(包含负数)
oninput ="value=value.replace(/[^\-\d.]/g, '').replace(/^(\-)*(\d+)\.(\d${3}).*$/, '$1$2.$3')" // 只能输入数字和小数,只保留一个小数点,只保留3位小数(包含负数)
oninput ="value=value.replace(/[^\-\d.]/g, '').replace(/(\.)(\d*)(\1*)/g,'$1$2').replace(/^(\-)*(\d+)\.(\d{2}).*$/, '$1.$2')" // 【终极】只能输入数字和小数,只保留一个小数点,只保留3位小数(包含负数)
使用示例:
<el-form-item label="角色Id">
<el-input type="text" size="small" width="50" v-model="param.roleId" placeholder="请输入数字" oninput="value=value.replace(/[^\d]/g,'')">
</el-form-item>
<el-input v-model="money" oninput ="value=value.replace(/[^\d.]/g,'')">
<span slot="suffix">/ 元 </span>
</el-input>
方法二(推荐👉)
使用封装的通用方法进行更细粒度的统一控制,可单独控制整数位和小数位个数。
主要做了如下限制:
- 限制只能填写数字类型;
- 限制整数和小数位数;
- 限制只有一个小数点;
- 限制不能以小数点开头;
- 限制整数不出现00的情况;
通用方法 CheckNum 源码:
!!这里挂载到 window
对象上,为了后面方便使用,记得及时清理不用的全局变量,可以在 beforeDestory`` 生命周期中直接把变量赋值为
null` 来清除引用。
/*
*@name: checkNum
*@param: intNum表示整数位个数, 默认0为不限制
*@param: decNum 表示小数位个数,默认0为没小数
*@desc:用于限制 input 输入的数字位数(包含小数位)
*/
window.checkNum = (obj, intNum = 0, decNum = 0) => {
var value = obj.value
var changeValue, t1, t2
if (decNum === 0) {
value = value.replace(/[^\d]/g, '') // 去除数字以外的字符,若要支持负数,可将此处正则改为/[^\-\d]/g
value = value.replace(/^0\d+/g, '0') // 防止整数位出现'00'的情况
obj.value = value
if (intNum !== 0) {
value = value.substr(0, intNum)
}
} else {
value = value.replace(/[^\d.]/g, '') // 去除数字和小数点以外的字符,若要支持负数,可将此处正则改为/[^\-\d.]/g
value = value.replace(/^[^\d]/g, '') // 保证第一个字符是数字,若要支持负数,可将此处正则改为/^[^\-\d]/g
value = value.replace(/\.{2}/g, '.') // 去除第二个小数点
value = value.replace(/^0\d+/g, '0')
changeValue = value.split('.')
if (changeValue.length > 1) {
// 表示用户输入的既有整数又有小数
if (intNum === 0) {
t1 = changeValue[0]
} else {
t1 = changeValue[0].substr(0, intNum)
}
t2 = changeValue[1].substr(0, decNum)
value = t1 + '.' + t2
} else {
if (intNum !== 0) {
value = value.substr(0, intNum)
}
}
}
if (obj.value !== value) {
obj.value = value
}
return value
}
使用示例:
<el-form-item label="角色Id">
<el-input type="text" size="small" width="50" v-model="param.roleId" placeholder="请输入数字" oninput="checkNum(this, 4, 1)">
</el-form-item>
记得及时清除引用
beforeDestroy() {
window.checkNum = null
}
表单验证场景
像上面那样使用的话,如果你的表单有验证或者是动态表单的情况下可能会有 bug,导致表单验证状态不对。
因为绑定的原生input
事件没有去更新表单里绑定的字段,导致 vue 这边不知道值变了,也就无法触发el-form
再执行一次验证,此时可以像下面这样用。
在你的 vue 文件的 methods
中加入一个方法,包装一下 checkNum
方法,手动更新一下表单里绑定的值,当然你也可以把 checkNum
直接搬过来,下面是相关代码(你也可以直接放到 mixin
中,在多个页面使用)。
import { checkNum } from '@/utils/common'
export default {
methods: {
// 校验 el-input 仅填写数字
validateNum(e, row, field) {
const value = checkNum(e.target || e.srcElement)
row[field] = value !== '' ? +value : '' // 注意为空的时候不要转数字
}
}
}
模板中像下面这样使用即可:
<el-form-item
:prop="`tableData[${scope.$index}].number_of_posts`"
:rules="rulesTable.number_of_posts"
>
<el-input
size="small"
@input.native="
validateNum($event, scope.row, 'number_of_posts') "
v-model.number="scope.row.number_of_posts"
/>
</el-form-item>
更新 Vue3 中的用法
只是一点小修改,直接上代码吧!
定义 checkNum 方法
/*
* @name: checkNum
* @param: intNum表示整数位个数,默认0为不限制
* @param: decNum表示小数位个数,默认0为没小数
* @param: maxLength用于限制输入的数字位数(包含小数位)
* @param: max用于限制输入的数字最大值
* @param: min用于限制输入的数字最小值
*/
export const checkNum = (obj: any, intNum = 0, decNum = 0, maxLength = 0, max = 0, min = 0) => {
let value = obj.value
let changeValue: string, t1: string, t2: string
if (decNum === 0) {
value = value.replace(/[^\d]/g, '') // 去除数字以外的字符,若要支持负数,可将此处正则改为/[^\-\d]/g
value = value.replace(/^0\d+/g, '0') // 防止整数位出现'00'的情况
obj.value = value
if (intNum !== 0) {
value = value.substr(0, intNum)
}
} else {
// value = value.replace(/[^\d.]/g, '') // 去除数字和小数点以外的字符,若要支持负数,可将此处正则改为/[^\-\d.]/g
value = value.replace(/[^\-\d.]/g, '') // 去除数字和小数点以外的字符,若要支持负数,可将此处正则改为/[^\-\d.]/g
// value = value.replace(/^[^\d]/g, '') // 保证第一个字符是数字,若要支持负数,可将此处正则改为/^[^\-\d]/g
value = value.replace(/^[^\-\d]/g, '') // 保证第一个字符是数字,若要支持负数,可将此处正则改为/^[^\-\d]/g
value = value.replace(/\.{2}/g, '.') // 去除第二个小数点
value = value.replace(/^0\d+/g, '0')
changeValue = value.split('.')
if (changeValue.length > 1) {
// 表示用户输入的既有整数又有小数
if (intNum === 0) {
t1 = changeValue[0]
} else {
t1 = changeValue[0].slice(0, intNum)
}
t2 = changeValue[1].slice(0, decNum)
value = t1 + '.' + t2
} else {
if (intNum !== 0) {
value = value.substr(0, intNum)
}
}
}
if (maxLength !== 0) {
value = value.slice(0, maxLength)
}
if (max !== 0 && value > max) {
value = max
}
if (min !== 0 && value < min) {
value = min
}
if (obj.value !== value) {
obj.value = value
}
return value
}
定义 hooks (也可直接写到 vue 文件中)
import { checkNum } from '@/utils/common'
export const useInputNumber = () => {
/*
* @name: validateNum 校验el-input仅填写数字、负数、小数
* @param: val表示当前输入的值
* @param: row表示表单当前行数据(根据自己实际情况修改)
* @param: field表示表单字段名
* @param: intNum表示整数位个数,默认0为不限制
* @param: decNum表示小数位个数,默认0为没小数
* @param: maxLength用于限制输入的数字位数,默认0(包含小数位)
* @param: max用于限制输入的数字最大值
* @param: min用于限制输入的数字最小值
*/
const validateNum = (
val: any,
row: any,
field: string,
intNum = 0,
decNum = 0,
maxLength = 0,
max = 0,
min = 0
) => {
const value = checkNum({ value: val }, intNum, decNum, maxLength, max, min)
row[field] = value // 注意:这里的值可能是字符串也可能是数字
}
return [validateNum]
}
在 vue 文件中使用
<template>
<el-form-item :prop="`kt_list[${index}].start`" :rules="formRuleTask.start" label="起始值:">
<el-input v-model="item.start" @input="validateNum($event, item, 'start', 0, 2, 10)"/>
</el-form-item>
</template>
<script setup lang="ts">
import { useInputNumber } from '@/hooks/number'
const [validateNum] = useInputNumber() // 限制el-input输入数字
</script>
参考:
replace 正则表达式,N位小数点
input框只能输入数字及一位小数点
对输入框的整数位数和小数位数做限制
阻止中文输入法输入拼音的时候触发input事件
评论区