侧边栏壁纸
博主头像
M酷博主等级

一帆风顺 ⛵️⛵️⛵️

  • 累计撰写 45 篇文章
  • 累计创建 40 个标签
  • 累计收到 456 条评论

目 录CONTENT

文章目录

限制 el-input 只能输入数字

M酷
2021-04-16 / 3 评论 / 15 点赞 / 13,489 阅读 / 6,476 字 / 正在检测是否收录...
广告 广告

背景:

在日常项目开发过程中,我们经常会用到 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事件

15
广告 广告

评论区