如何在Vue2.0和Element-UI中限制el-input只能输入纯数字?

业务场景:el-input框框只能输入数字类型
技术:vue2.0 element-ui
问题:使用el-input 可以限制数字,但是针对输入的“e”无法限制,并且输入类似于(0-2)这样的表达式也无法限制,甚至input方法无法捕获.所以想知道为什么输入(0-2)触发不了@input方法?
链接:https://codepen.io/beiwuFirst/pen/QwLZrjK

<el-input
  placeholder="请输入内容"
  v-model.number="input"
  type="number"
  @input="inputNumber"
  clearable>
</el-input>
  {{newText}}
</div>
data() {
      return {
        input: '',
        newText:""
      }
    },
  methods:{
    inputNumber(val){
      this.newText = val.toString()
    }
  }

输入0-2,newText这个值都不显示,并且不触发inputNumber函数
如图:
image.png

  1. v-model.number="input" type="number" 感觉限制不住,请大佬能够告知一下,谢谢
  2. 知道正则表达式可以限制,但是不知道为啥0-2触发不了input方法0F17212E.png
阅读 767
4 个回答

<el-input> 组件的 v-model.number 会将输入框的值绑定为数字类型。当输入非数字字符(如 -)时,v-model.number 会尝试将其转换为数字,但由于 - 不是有效的数字字符,input 的值会变为 NaN,导致后续的输入事件无法正确触发。

根据你提供的代码片段,只需要在 inputNumber 事件中,将 newText 的赋值移动一下位置即可。

  inputNumber(val) {
      // this.newText = val
      // 只允许输入正整数
      const regex = /^[1-9]\d*$/;
      if (regex.test(val)) {
        this.newText = val;
        this.input = val; // 更新 input 的值
      } else {
        this.input = this.newText; // 恢复到上一个有效值
      }
    }

只能输入正整数的情况

<template>
  <div>
    <el-input
      placeholder="请输入正整数"
      v-model="input"
      @input="validateInput"
      clearable>
    </el-input>
    {{ newText }}
  </div>
</template>

<script>
export default {
  data() {
    return {
      input: '',
      newText: ''
    };
  },
  methods: {
    validateInput(val) {
      // 只允许输入正整数
      const regex = /^[1-9]\d*$/;
      if (regex.test(val)) {
        this.newText = val;
      } else {
        this.input = this.newText; // 恢复到上一个有效值
      }
    }
  }
};
</script>
@input="value = value.replace(/[^\d]/g,'')" //只可以输入正整数,不可以输入小数点

@input="value=value.replace(/[^0-9.]/g,'')" //只可以输入正整数,可以输入小数点

可以写一个自定义指令, 输入的过程中替换掉不合规的字符

/*
 限制只能输入数字-正整数 v-input-number
 限制只能输入数字-正负整数 v-input-number.minus
 限制只能输入数字-验证码/状态码(允许首位为0, 如012345) v-input-number.isCode
 限制只能输入数字-正数包含两位小数 v-input-number.float="2"
 限制只能输入数字-正负数包含两位小数 v-input-number.minus.float="2"
*/
Vue.directive('input-number', {
  bind(el, binding, vnode) {
    const ele = el.tagName === 'INPUT' ? el : el.querySelector('input');
    const pasteFun = onPaste(ele, binding, vnode);
    ele.addEventListener('keyup', onInput(ele, binding, vnode), false);
    ele.addEventListener('blur', onBlur(ele, binding, vnode, pasteFun), false);
    // 防止用户通过鼠标右键粘贴时 不触发input事件 导致无法控制输入框内容格式
    ele.addEventListener('mousedown', () => {
      // document.addEventListener('contextmenu', function(event) {
      //   if (event.target.tagName.toLowerCase() === 'input') {
      //     event.preventDefault(); // 阻止默认的右键菜单
      //   }
      // });
      document.addEventListener('paste', pasteFun);
    }, false);
  }
});

function onInput(ele, binding, vnode) {
  return () => {
    let val = ele.value;
    const firstStr = val.charAt(0);
    if (binding.modifiers.float) { // 是否允许输入小数
      val = val.replace(/[^\d.]/g, ''); // 清除 数字、点以外的字符
      val = val.replace('.', '$#$').replace(/\./g, '').replace('$#$', '.'); // 只保留第一个点, 清除多余的
      val = val.replace(/^\./g, '0.'); // 第一个字符如果是.号,则补充前缀0
      let pointKeep = parseInt(binding.value); // 期望保留的小数位数
      if (!isNaN(pointKeep)) {
        if (!Number.isInteger(pointKeep) || pointKeep < 0) {
          pointKeep = 0;
        }
        const reg = new RegExp('^(\\d+)\\.(\\d\{' + pointKeep + '}).*$');
        if (pointKeep === 0) {
          val = val.replace(reg, '$1'); // 不需要小数点
        } else {
          val = val.replace(reg, '$1.$2') // 保留小数点后指定的位数
        }
      }
    } else {
      val = val.replace(/[\D]/g, '');
    }

    // isCode 是否是状态码/验证码 若是 则允许首位为0; 否则 若不是只输入0 并且以0开头 但不是以0.开头, 去除首位0
    if (!binding.modifiers.isCode && val.length > 1 && val.startsWith('0') && !val.startsWith('0.')) {
      val = val.substring(1);
    }
  
    if (binding.modifiers.minus && firstStr === '-') { // 允许输入负数 且首位字符为负号
      val = firstStr + val;
    }

    ele.value = val;
    // 触发数据的双向绑定
    if (vnode.componentInstance) {
      vnode.componentInstance.$emit('input', ele.value);
    } else {
      vnode.elm.dispatchEvent(new CustomEvent('input', { detail: ele.value }));
    }
  }
}

// 输入框失去焦点时 判断若只输入了负号, 则置为空; (不放在onInput函数中处理是为了避免无法先输入负号)
function onBlur(ele, binding, vnode, pasteFun) {
  return () => {
    if (ele.value === '-') {
      ele.value = '';
      // 触发数据的双向绑定以及change事件
      if (vnode.componentInstance) {
        vnode.componentInstance.$emit('input', ele.value);
        vnode.componentInstance.$emit('change', ele.value);
      } else {
        vnode.elm.dispatchEvent(new CustomEvent('input', { detail: ele.value }));
        vnode.elm.dispatchEvent(new CustomEvent('change', { detail: ele.value }));
      }
    }
    // 失去焦点时 移除粘贴事件的监听
    document.removeEventListener('paste', pasteFun);
  }
}

// 粘贴事件
function onPaste(ele, binding, vnode) {
  return (event) => {
    if (ele === event.target) {
      // 此时 ele.value 还是空的, 需要延时处理; (event.clipboardData.getData('text'))
      setTimeout(() => {
        onInput(ele, binding, vnode)();
      })
    }
  }
}
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏