如何限制多个输入字段(使用 v-model)只接受 Vue.js 中的数字(不为每个输入字段重复代码)?
How to limit multiple input fields (which use v-model) to only accept numbers in Vue.js (without repeating code for every input field)?
我有多个输入字段,我想限制它们只接受 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-这些输入字段上的模型。添加 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, "");
}
}
有什么方法可以解决它并使它像我的解决方案一样简单而无需重复代码? 最好也有复制粘贴证明的解决方案。 欢迎所有建议!提前致谢!
也许你可以试试这个:
<input type="number" name="priceMax" class="input" @input="correctNumberInput" v-model.number="priceMax" />
来自该站点:click。
我尝试测试了一些代码。这是我的 (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 中的数字。
我想禁止用户输入除 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-这些输入字段上的模型。添加 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, "");
}
}
有什么方法可以解决它并使它像我的解决方案一样简单而无需重复代码? 最好也有复制粘贴证明的解决方案。 欢迎所有建议!提前致谢!
也许你可以试试这个:
<input type="number" name="priceMax" class="input" @input="correctNumberInput" v-model.number="priceMax" />
来自该站点:click。
我尝试测试了一些代码。这是我的 (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 无论如何都不起作用,只能通过鼠标)。