vue中做一个最多输入一位小数且可以为负数的输入框(包含最前面最后面为小数点及多个-符号与前导零校验)

需求背景

日常开发中会有对input做校验的需求  例如做一个只可以输入一位小数及可以为负数的输入框  这时候会出现0开头、多个--、多个小数点插入或开头结尾为小数点的情况

实现过程

<el-input
            style="width: 80px;"
            v-model="dataForm.low"
            @input="lowHandleInput($event, 'low')"
            @blur="lowValueBlur('low')"
          ></el-input>
const formatValue=(value:any)=> {
      // 格式化输入的值,确保最多1位小数
      const [integerPart, decimalPart] = value.split(".");
      if (decimalPart && decimalPart.length > 1) {
        return `${integerPart}.${decimalPart.slice(0, 1)}`;
      }
      //只保留最前面的.
      value=value.replace(/\.(?=.*\.)/g, '');
      //多个-处理
      const firstChar = value[0] || '';
      const restOfString = value.slice(1).replace(/-/g, '');
      value= firstChar + restOfString;
      return value;
    }
  const  lowHandleInput=(value:any,name:string)=> {
      //基础格式检测
      const regex = /^[-]?\d*(\.\d{0,1})?$/;
      if (!regex.test(value)) {
        dataForm[name] = formatValue(
          value.replace(/[^-\d.]/g, "").replace(/(\.\d*)?\.$/, "$1"),
        );
        return;
      }
      dataForm[name] = formatValue(value);
    }
  const  lowValueBlur=(name:string)=> {
      if (dataForm[name].length) {
        //最后一位为.
        if (dataForm[name][dataForm[name].length - 1] == ".") {
          dataForm[name] = dataForm[name].slice(0, -1);
        }
        //最前面为.
        if (dataForm[name][0] == ".") {
          dataForm[name] = dataForm[name].slice(1);
        }
        //将前导零忽略
        dataForm[name]=String(Number(dataForm[name]));
      }
  }

失焦及输入事件可传key进行复用  若小数点需要支持多位 例如3位时可将正则及slice内数字1进行替换为3

<think>好的,我现在需要解决用户的问题:在ElementUI的el-form-item中限制输入最多三位小数不允许负数。用户之前已经得到了一些关于支持负数的解决方案,现在希望调整,去掉负数支持,同时保持最多三位小数的限制。 首先,回顾之前的回答,我们使用了输入过滤和表单验证规则相结合的方法。现在需要调整正则表达式,去掉负数的支持。原来的正则表达式是/^-?\d+(\.\d{1,3})?$/,其中^-?允许可选的负号。要禁止负数,应该将负号部分去掉,改为^\\d+(\\.\\d{1,3})?$。这样整数部分必须是非负整数,小数部分最多三位。 接下来,输入过滤部分也需要修改。之前的handleDecimalInput方法允许负号,现在需要移除对负号的处理。原本的正则替换中有保留负号和小数点的部分,现在应该只保留数字小数点。例如,替换掉[^\d.-]中的负号,改为[^\d.],这样用户无法输入负号。 还需要检查是否有其他部分涉及到负号的处理,比如多个负号的禁止。在原来的代码中,有replace(/(-.*)-/g, '$1')来防止多个负号,现在因为不允许负数,所以这部分可以移除,避免用户输入任何负号。 然后,表单验证规则中的pattern应该更新为正则表达式,确保输入为非负数最多三位小数。同时,可能需要添加额外的验证规则,比如使用validator函数来进一步检查数值范围或其他条件,但用户当前的需求只是三位小数和非负数,所以正则应该足够。 另外,示例中的引用[1]提到了处理负号和小数点的方法,但用户现在不需要负号,所以需要调整这部分逻辑,确保任何负号输入都被过滤掉。例如,在输入过滤时,一旦检测到负号,就立即移除。 还需要测试边界情况,比如用户输入0.000是否允许,或者输入整数部分为的情况,如0.123。正则表达式应该正确处理这些情况,确保整数部分至少有一位数字小数部分可有可无,但最多三位。 此外,输入框的类型可能需要设置为text,而不是number,因为type="number"在某些浏览器中可能允许输入负号,或者有默认的上下箭头,但用户可能希望完全控制输入内容,所以保持type为text,并通过正则和过滤来限制输入后,确保表单提交时的验证能够正确触发,比如在blur或change事件时检查输入是否符合规则,并给出相应的提示信息。例如,当用户输入负号时,输入框应该立即过滤掉,并在表单提交时提示不允许负数。 总结步骤: 1. 修改输入过滤的正则表达式,禁止负号输入。 2. 更新表单验证的正则表达式,去掉负号支持。 3. 移除处理负号的相关代码。 4. 测试各种输入情况,确保非负数和三位小数限制有效。 5. 调整提示信息,明确说明不允许负数最多三位小数。</think>在ElementUI中实现**非负数最多三位小数**的输入限制,可通过以下方案实现: --- ### **完整实现代码** ```vue <template> <el-form :model="form" :rules="rules" ref="formRef"> <el-form-item label="数值" prop="number"> <el-input v-model="form.number" @input="handleInput" placeholder="请输入负数最多三位小数" ></el-input> </el-form-item> </el-form> </template> <script> export default { data() { return { form: { number: '' }, rules: { number: [ { required: true, message: '不能为空' }, { pattern: /^\d+(\.\d{1,3})?$/, // 关键正则表达式 message: '必须为非负数最多三位小数', trigger: ['blur', 'change'] } ] } } }, methods: { handleInput(value) { // 过滤所有非数字小数点的字符 let filtered = value .replace(/[^\d.]/g, '') // 移除非数字小数点[^1] .replace(/(\..*)\./g, '$1'); // 禁止多个小数点 // 处理小数位数限制 const parts = filtered.split('.'); if (parts.length > 1) { filtered = `${parts[0]}.${parts[1].slice(0, 3)}`; } // 禁止以0开头的整数(可选) if (parts[0].length > 1 && parts[0].startsWith('0')) { filtered = filtered.replace(/^0+/, '0'); } this.form.number = filtered; } } } </script> ``` --- ### **实现原理详解** #### 1. 正则表达式核心逻辑 ```javascript /^\d+(\.\d{1,3})?$/ // 解读: ^ // 起始符 \d+ // 必须包含1个以上数字(禁止小数点输入(\.\d{1,3})? // 可选小数部分(1-3位数字) $ // 结束符 ``` #### 2. 输入过滤机制 - **实时过滤**:通过`@input`事件触发`handleInput`方法 - **字符过滤**:`replace(/[^\d.]/g, '')`移除非数字小数点[^1] - **小数点控制**:`replace(/(\..*)\./g, '$1')`确保最多一个小数点 - **小数截断**:自动截断超过三位的小数部分 #### 3. 验证规则组合 - **必填校验**:`required: true`确保字段非空 - **正则校验**:`pattern`验证数值格式 - **多重触发**:`trigger: ['blur', 'change']`实现失焦和内容变化时双重校验[^2] --- ### **扩展优化方案** #### 1. 禁止小数点输入(如".123") ```javascript handleInput(value) { if (value.startsWith('.')) { value = '0' + value; } // 原有过滤逻辑... } ``` #### 2. 整数部分千分位格式化 ```javascript handleInput(value) { // 过滤后处理整数部分 const [intPart, decimalPart] = filtered.split('.'); const formattedInt = intPart.replace(/\B(?=(\d{3})+(?!\d))/g, ','); this.form.number = decimalPart ? `${formattedInt}.${decimalPart}` : formattedInt; } ``` #### 3. 服务端数据转换 ```javascript // 提交前转换数据格式 submitForm() { const rawValue = this.form.number.replace(/,/g, ''); const numericValue = parseFloat(rawValue); } ``` --- ### **常见问题处理** 1. **初始值显示问题**: ```javascript data() { return { form: { number: '0.000' } // 默认显示三位小数 } } ``` 2. **科学计数法屏蔽**: ```javascript handleInput(value) { if (/e/i.test(value)) { this.form.number = value.replace(/e/gi, ''); } } ``` 3. **粘贴内容过滤**: ```javascript <el-input @paste.native="handlePaste" ></el-input> handlePaste(e) { const pasteData = e.clipboardData.getData('text'); if (!/^\d+(\.\d{1,3})?$/.test(pasteData)) { e.preventDefault(); } } ``` --- ### **佳实践建议** 1. **输入类型选择**: ```vue <el-input type="text" // 必须使用text类型,number类型会允许负数输入 inputmode="decimal" // 移动端调起数字键盘 ></el-input> ``` 2. **错误提示优化**: ```javascript rules: { number: [ { validator: (rule, value, callback) => { if (value === '') return callback(new Error('不能为空')); if (!/^\d+(\.\d{1,3})?$/.test(value)) { if (/-/.test(value)) { callback(new Error('禁止输入负数')); } else { callback(new Error('小数位不能超过3位')); } } callback(); } } ] } ``` 3. **国际化方案**: ```javascript // 匹配不同地区的小数点符号 replace(/[^\d,]/g, '') // 欧洲地区使用逗号作为小数点 ``` --- **相关问题**: 1. 如何实现ElementUI输入框同时限制整数部分不超过10位? 2. Vue中如何防止用户输入空格字符? 3. ElementUI表单验证如何实现小数位动态配置?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值