【问题标题】:Filter input text only accept number and dot vue.js过滤输入文本只接受数字和点 vue.js
【发布时间】:2017-02-08 11:31:45
【问题描述】:

我有一个文本框,只想接受数字和句点“。”使用 VueJS 时。任何人都可以帮助编写代码吗?我是 Vue 新手。

【问题讨论】:

  • 我知道这是个老问题,但它在 Google 搜索结果中名列前茅。因此,这里是有类似问题的用户的解决方案。我认为这里的所有解决方案都很复杂。最简单的做法是添加@input 事件并替换所有非数字和点。 this.message.replace(/[^0-9.]/g,'');。这是一个 fiddle 来演示。
  • @KalimahApps - 允许多个点 = 问题。
  • 说真的,不要进一步阅读@Kalimah 的建议。我在 15 秒内启用了它
  • @Kalimah 我真的很喜欢你的解决方案。这就是我首先做的,但问题是当我有多个只接受数字的文本字段时。如何在不重复代码的情况下做到这一点?我在“@input”事件上使用event.target.value = event.target.value.replace(/[^0-9]/g, ""); 创建了一个适用于所有字段的函数,但是当我添加v-model(因为我出于不同的原因需要它)时,现在它不起作用......请帮忙。提前致谢!
  • @VasilijeBursac 你可以使用这个codepen

标签: vue.js


【解决方案1】:

您可以编写一个 Vue 方法,并且可以在 keypress 事件上调用该方法。查看this fiddle

更新:

添加源代码:

HTML

<div id="demo">
  <input v-model="message" @keypress="isNumber($event)">
</div>

Vue.js

var data = {
  message: 1234.34
}

var demo = new Vue({
  el: '#demo',
  data: data,
  methods: {
    isNumber: function(evt) {
      evt = (evt) ? evt : window.event;
      var charCode = (evt.which) ? evt.which : evt.keyCode;
      if ((charCode > 31 && (charCode < 48 || charCode > 57)) && charCode !== 46) {
        evt.preventDefault();;
      } else {
        return true;
      }
    }
  }
});

【讨论】:

  • 为了不让charCode !== 46改成charCode === 46的句号
  • 我实现了这个,它运行良好,除了一件事。我必须在数据中定义事件,否则会引发控制台错误。我只是添加了“事件:null”,没有更多错误!
  • 其实绑定应该是v-on:keypress="isNumber($event)"
  • 我在你的 js fiddle 中试过,我可以输入超过 1 个句点。它只能是 1。该怎么做?
  • 这个怎么处理粘贴?
【解决方案2】:

您应该将输入更改为 type="number" 以更准确地反映您的行为。然后你可以使用内置的 Vue.js 指令v-model.number

用法:

<input type="number" v-model.number="data.myNumberData"/>

【讨论】:

  • 一些浏览器有onScroll 代表type=number,它会增加/减少值。
  • 使用type=number 并不总是一个很好的数字输入解决方案,因为浏览器会以不同的方式设置输入框并添加递增/递减按钮。
  • 此答案有效,但只允许输入一个字符 (E)。为什么有什么原因?
  • @SudhirKGupta 科学记数法,例如 1.2e-1,即 0.12
  • 这仍然允许包含多个小数点的条目,例如 1.2.3.4.5
【解决方案3】:

简短易懂。

HTML

 <input @keypress="onlyNumber" type="text">

VUE JS

onlyNumber ($event) {
   //console.log($event.keyCode); //keyCodes value
   let keyCode = ($event.keyCode ? $event.keyCode : $event.which);
   if ((keyCode < 48 || keyCode > 57) && keyCode !== 46) { // 46 is dot
      $event.preventDefault();
   }
}

【讨论】:

  • 这种方式“退格”键也是不允许的。如果我想删除以前的号码并添加另一个号码怎么办?
  • 您可以使用此代码查看关键代码 console.log($event.keyCode); //keyCodes值
  • 如何限制输入只有一个点?
【解决方案4】:

这是我的解决方案。这里的大多数答案已被弃用。此外,输入值始终返回一个字符串,即使您键入一个数字也是如此。因此,正因为如此,这里的一些解决方案对我不起作用。

在我的例子中,我不想要小数点,但为了这个线程的目的,我将它添加到数组中。

<b-form-input v-model.number="quantity" @keypress="isNumber($event)" type="number"></b-form-input>
isNumber (evt: KeyboardEvent): void {
    const keysAllowed: string[] = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '.'];
    const keyPressed: string = evt.key;
    
    if (!keysAllowed.includes(keyPressed)) {
           evt.preventDefault()
    }
}

【讨论】:

  • 然而,我最喜欢的答案是用 TypeScript 编写的。
【解决方案5】:

在一行中完成此操作的简单方法:

IsNumber(event) {
  if (!/\d/.test(event.key) && event.key !== '.') return event.preventDefault();
}

【讨论】:

  • 我不知道性能(因为正则表达式),但是如果您正在检查数字,这应该是唯一的答案......
  • 为我工作if (!/^[0-9]+$/.test(event.key) || event.key === '.') return event.preventDefault();
  • allowDecimalChars(event: KeyboardEvent) { if (/[^.0-9]/.test(event.key)) { event.preventDefault() } }
【解决方案6】:

通过使用以下指令设置 v-restrict.number.decimal,这是处理特定问题(仅限数字和“点”)的更好方法。它还有一些奖励代码来支持仅字母或字母数字。你也可以只允许“点”,虽然我不知道你为什么会这样做。如果快速打字,它不会允许额外的字符“偷偷溜走”。它还支持复制/粘贴、删除和其他一些用户希望仍然可以通过输入工作的键:

Vue.directive('restrict', {
  bind (el, binding) {
    el.addEventListener('keydown', (e) => {
      // delete, backpsace, tab, escape, enter,
      let special = [46, 8, 9, 27, 13]
      if (binding.modifiers['decimal']) {
        // decimal(numpad), period
        special.push(110, 190)
      }
      // special from above
      if (special.indexOf(e.keyCode) !== -1 ||
        // Ctrl+A
        (e.keyCode === 65 && e.ctrlKey === true) ||
        // Ctrl+C
        (e.keyCode === 67 && e.ctrlKey === true) ||
        // Ctrl+X
        (e.keyCode === 88 && e.ctrlKey === true) ||
        // home, end, left, right
        (e.keyCode >= 35 && e.keyCode <= 39)) {
        return // allow
      }
      if ((binding.modifiers['alpha']) &&
        // a-z/A-Z
        (e.keyCode >= 65 && e.keyCode <= 90)) {
        return // allow
      }
      if ((binding.modifiers['number']) &&
        // number keys without shift
        ((!e.shiftKey && (e.keyCode >= 48 && e.keyCode <= 57)) ||
        // numpad number keys
        (e.keyCode >= 96 && e.keyCode <= 105))) {
        return // allow
      }
      // otherwise stop the keystroke
      e.preventDefault() // prevent
    }) // end addEventListener
  } // end bind
}) // end directive

使用方法:

<!-- number and decimal -->
<input
  v-model="test"
  v-ep-restrict.number.decimal
  ...
/>

<!-- alphanumeric (no decimal) -->
<input
  v-model="test2"
  v-ep-restrict.alpha.number
  ...
/>

<!-- alpha only -->
<input
  v-model="test3"
  v-ep-restrict.alpha
  ...
/>

这可以修改为几乎任何场景的基础,一个很好的关键代码列表是here

【讨论】:

  • 我喜欢这个答案,但可以更新它以说明 keyCode 被弃用吗?
【解决方案7】:

我通过 vue.js 过滤器解决了像你这样的问题。首先我创建了过滤器 - 比如说在 filters.js 文件中

export const JustDigits = () => {
  Vue.directive('digitsonly', (el, binding) => {
    if (/[\d\.]+/i.test(el.value)) {
      console.log('ok');
    } else {
      let newValue = el.value.replace(/[a-zA-Z]+/ig, '');
      el.value = newValue;
      console.log('should fix', newValue);
      binding.value = el.value;
    }
  });
};

然后在需要此功能的组件中我做了:

import {
  JustDigits
} from './filters';

JustDigits();

然后你就可以在模板中使用这个指令了:

 <input  v-model="myModel"
         v-digitsonly
         type="text"  
         maxlength="4"  class="form-control" id="myModel" name="my_model" />

请注意,我的正则表达式可能与您需要的不同,请随时修改它以及从字符串中删除字符的代码行let newValue = el.value.replace(/[a-zA-Z]+/ig, '');。我发布它只是为了向您展示 vue.js 提供的解决此类任务的可能解决方案之一。

【讨论】:

  • 如果您输入多个字母,有时会出现第二个字母。
  • 您可以避免快速输入额外字符,方法是在检查之前将值包装在半秒左右的去抖动(从 lodash 或 unsercore 导入)
【解决方案8】:

在以前的解决方案的基础上,为防止出现多个小数位,还将 v-model 传递给函数:

&lt;input v-model="message" v-on:keypress="isNumber($event, message)"&gt;

并修改isNumber方法如下:

isNumber(event, message) {
  if (!/\d/.test(event.key) &&  
    (event.key !== "." || /\./.test(message))  
  )  
    return event.preventDefault();  
}

要限制小数点后的位数,请在 isNumber 方法中添加以下行:

 if (/\.\d{2}/.test(message)) return event.preventDefault();

\d{2} 限制输入两位数。将此更改为 \d{1} 以限制为一个。

如其他答案所述,这不会阻止粘贴非数字数据。

【讨论】:

    【解决方案9】:

    我需要我的输入只允许数字,所以没有e 符号、加号、减号或.。 Vue 看起来很时髦,并且不会为 dot 之类的符号重新触发 @onkeypress

    这是我对这个问题的解决方案:

    <input
      onkeypress="return event.key === 'Enter'
        || (Number(event.key) >= 0
        && Number(event.key) <= 9"
      type="number"
    >
    

    我只取数字,限制在 0 到 9 之间,但我确实希望在 Enter 上启用表单提交,这将被上述方法排除 - 因此是 enter。

    【讨论】:

    • 条件中缺少括号,但效果很好! :thumbs-up:
    • onkeypress 现在在 Firefox 上已弃用
    【解决方案10】:

    你可以通过简单的html来处理这个

    <input type="number">
    

    在您的 app.css

    /* Chrome, Safari, Edge, Opera */
    input::-webkit-outer-spin-button,
    input::-webkit-inner-spin-button {
      -webkit-appearance: none;
      margin: 0;
    }
    
    /* this is for Firefox */
    input[type=number] {
      -moz-appearance: textfield;
    }
    

    样式代码将从您的数字输入字段中删除难看的箭头,是的,它接受点

    【讨论】:

      【解决方案11】:
      <v-text-field class='reqField' label="NUMBER" @keypress="isNumber($event)"></v-text-field>
      methods: {
          isNumber: function(evt) {
              evt = (evt) ? evt : window.event;
              var charCode = (evt.which) ? evt.which : evt.keyCode;
              if (charCode > 31 && (charCode < 48 || charCode > 57) && (charCode != 9)) {
                  evt.preventDefault();
              } else {
                  return true;
              }
              `enter code here`
          },
      }
      

      【讨论】:

      • 请解释一下你的答案
      【解决方案12】:

      为什么不使用像vue-the-maskcleave.js 这样的外部掩码库?

      例如,使用 vue-the-mask,您可以像这样轻松地使用他们的指令:

      <input type="text" name="some-name" id="some-id" v-model="some.value" v-mask="'##.##.##.##.###'">
      

      【讨论】:

      • vue-the-mask Rocks
      • 为什么不呢?因为您总是希望尽量减少外部库。
      【解决方案13】:

      你可以使用这个库https://www.npmjs.com/package/vue-input-only-number

      import onlyInt, { onlyFloat } from 'vue-input-only-number';
      
      Vue.use(onlyInt);
      Vue.use(onlyFloat);
      
      <input type="text" v-int>
      <input type="text" v-float>
      

      【讨论】:

        【解决方案14】:

        只要判断是否为 nan,现在就可以阻止默认了

        <input @keypress="isNumber">
        
        isNumber (val) {
          if (isNaN(Number(val.key))) {
            return val.preventDefault();
          }
        }
        

        【讨论】:

          【解决方案15】:

          input 事件可以对任何类型的更改(程序或用户类型)做出反应,它比keypresskeydown 更强大。

          <input @input="preventInvalidInput">
          
          preventInvalidInput(event) {
            let value = event.target.value;
            // Check if value is number
            let isValid = +value == +value;
              
            if (!isValid) {
              // input event is not cancellable by preventDefault() 
              // so we have to use the below approach to reset the current value to previous one
              var resetEvent = document.createEvent('Event');
              resetEvent.initEvent('input', true, true);
              event.target.value = event.target._value;
              event.target.dispatchEvent(resetEvent);
            }
          }
          

          【讨论】:

            【解决方案16】:

            我无法找到完美的解决方案,因为有些工作用于输入但不适用于复制和粘贴,有些则相反。这个解决方案对我有用。它可以防止负数、输入“e”、复制和粘贴“e”文本。

            我使用 mixin,所以我可以在任何地方重复使用。

            const numberOnlyMixin = {
                directives: {
                numericOnly: {
                    bind(el, binding, vnode) {
            
                    // console.log(el, binding);
            
                    // this two prevent from copy&paste non-number text, including "e".
                    // need to have both together to take effect.
                    el.type = 'number';
                    el.addEventListener('input', (e) => {
                        // console.log('input', e);
                        // console.log(el.validity);
                        return el.validity.valid || (el.value = '');
                    });
            
                    // this prevents from typing non-number text, including "e".
                    el.addEventListener('keypress', (e) => {
                        let charCode = (e.which) ? e.which : e.keyCode;
                        if ((charCode > 31 && (charCode < 48 || charCode > 57)) && charCode !== 46) {
                        e.preventDefault();
                        } else {
                        return true;
                        }
                    });
                    }
                }
                },
            };
            
            export {numberOnlyMixin}
            

            在您的组件中,添加到您的输入。

            <input v-model="myData" v-numericOnly />
            

            【讨论】:

            • 潜在的内存泄漏!这个解决方案生产准备好了吗?我认为您需要在元素离开 DOM 时取消绑定事件侦听器。
            【解决方案17】:

            你可以在里面使用数字类型:

            <input type="number" class="yourCssClass" placeholder="someText" id="someId" />
            

            然后,添加移除上/下微调器所需的 CSS:

            /* Chrome, Safari, Edge, Opera */
              input::-webkit-outer-spin-button,
              input::-webkit-inner-spin-button {
                -webkit-appearance: none;
                margin: 0;
              }
            
              /* Firefox */
              input[type=number] {
                -moz-appearance: textfield;
              }
            

            【讨论】:

              猜你喜欢
              • 2014-03-26
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多