【问题标题】:How to limit multiple input fields (which use v-model) to only accept numbers in Vue.js (without repeating code for every input field)?如何限制多个输入字段(使用 v-model)仅接受 Vue.js 中的数字(不为每个输入字段重复代码)?
【发布时间】:2020-12-14 15:17:11
【问题描述】:

我有多个输入字段,我想在 Vue.js 中限制它们只接受数字
我想禁止用户输入除 0-9 数字以外的任何字符。 我已经通过这样做成功地做到了(这个解决方案复制粘贴证明):

Vue.js 模板中的代码:

<input type="text" name="priceMax" class="input" @input="correctNumberInput" />

删除除数字以外的所有内容的方法:

correctNumberInput: function(event){   
          event.target.value = event.target.value.replace(/[^0-9]/g, "");
        }

这在多个领域都非常有效。

问题来了:由于不同的原因,我需要在这些输入上使用 v-model字段。添加 v-model 后,我的方法不再起作用。我想这是因为 v-model 在后台也使用了输入事件。所以只添加“v-model”,它就无法工作:

<input type="text" name="priceMax" class="input" @input="correctNumberInput" v-model="priceMax" />

我想到的可能解决方案很少,但所有解决方案都包含大量重复代码。

例如,我可以为每个输入字段添加观察者,但这将是很多重复的代码(因为我需要为每个输入字段都这样做)。我有 5 个输入字段,所以基本上我需要编写 5 个几乎相同的观察者。如果可能的话,我想避免这种情况......例如:

watch:{
   number(){
      this.priceMax = this.priceMax.replace(/[^0-9]/g, "");
   }
}

有没有什么方法可以解决它,让它像我的解决方案一样简单无需重复代码如果还提供可复制粘贴证明的解决方案,那就太好了。 欢迎所有建议!提前致谢!

【问题讨论】:

  • 也许this one 会有所帮助
  • 感谢您的回答!这些解决方案很好,但对我来说最大的问题是重复代码。我有 5 个输入字段,所以基本上我需要编写 5 个几乎相同的观察者。如果可能的话,我想避免这种情况......

标签: javascript vue.js input vuejs2 v-model


【解决方案1】:

我尝试测试一些代码。这是我所拥有的 (link to the example):

<template>
  <div>
    <div>
      <input
        type="text"
        name="priceMin"
        class="input"
        v-model="priceMin"
        @input="correctNumberInput"
      >
      <label v-html="priceMin"></label>
    </div>
    <div>
      <input
        type="text"
        name="priceMax"
        class="input"
        v-model="priceMax"
        @input="correctNumberInput"
      >
      <label v-html="priceMax"></label>
    </div>
  </div>
</template>

<script>
export default {
  name: "MyInput",
  data: () => {
    return {
      priceMin: "",
      priceMax: ""
    };
  },
  methods: {
    correctNumberInput: function(event, data) {
      const name = event.target.name;
      let value = String(this[name]).replace(/[^0-9]/g, "");
      if (value) {
        this[name] = parseInt(value, 10);
      } else {
        this[name] = "";
      }
    }
  }
};
</script>

<style scoped>
input {
  border: 1px solid black;
}
</style>

这是代码:

correctNumberInput: function(event, data) {
  const name = event.target.name;
  let value = String(this[name]).replace(/[^0-9]/g, "");
  if (value) {
    this[name] = parseInt(value, 10);
  } else {
    this[name] = "";
  }
}

所以我使用了你的函数,但我没有更改event.target.value,我正在更改data。所以我需要知道该数据的名称,这就是为什么我使用输入字段中的name 属性(const name = event.target.name;

更新

如果我们有input type=number,那么它在@input 回调中有一个奇怪的(空)值。看来,最好使用键盘过滤器(example here):

拥有键盘过滤器的主要思想:

filterDigitKeys: function(event) {
  const code = window.Event ? event.which : event.keyCode;
  const isSpecial =
    code === 37 ||
    code === 39 ||
    code === 8 ||
    code === 46 ||
    code === 35 ||
    code === 36;
  const isDigit = code >= 48 && code <= 57;
  const isKeypad = code >= 96 && code <= 105;
  if (!isSpecial && !isDigit && !isKeypad) {
    // if not number or special (arrows, delete, home, end)
    event.preventDefault();
    return false;
  }
}

并将其附加到输入:

<input type="number" min="0" name="numberInput" class="input"
    v-model.number="numberInput" @keydown="filterDigitKeys">

注意:如果我们只保留@keydown 处理程序,那么我们将不会过滤插入到输入中的文本(但 ctrl+v 无论如何都不起作用,只能通过鼠标)。

【讨论】:

  • 非常感谢!这是我一直在寻找的解决方案!非常聪明和优雅。我只是不知道怎么做,因为我是 Vue.js 的初学者,我不知道 "[]" 和 "this" 的用法。通过您的回答,我肯定学到了一些新东西!再次感谢!
  • @VasilijeBursac 这不是来自 Vue,这是来自 JS 本身。任何对象实际上都是一张地图,所以a.ba['b'] 的作用是一样的。
  • 哦,我不知道这是同一回事。谢谢你的精彩解释!
  • 很抱歉打扰您,但是您知道为什么此代码不适用于数字输入字段吗?如果您尝试在数字输入字段中键入“e”、“-”等,它仍然会在字段中显示,它不会将其替换为“”(空字符串)。我不明白为什么它不起作用,因为我之前在数字字段上使用过相同的功能并且效果很好。查看带有添加数字字段的代码:example with added number input field
  • @VasilijeBursac 我已将更新添加到我的答案中。检查一下
【解决方案2】:

也许你可以试试这个:

<input type="number" name="priceMax" class="input" @input="correctNumberInput" v-model.number="priceMax" />

来自该网站:click

【讨论】:

  • 感谢您的回答!不幸的是,这没有帮助,因为我想禁止用户输入除 0-9 数字以外的任何字符,并且您的解决方案只会将用户输入从字符串类型转换为数字。
猜你喜欢
  • 1970-01-01
  • 2017-05-18
  • 1970-01-01
  • 2015-03-31
  • 2013-01-14
  • 2014-06-26
  • 2021-09-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多