我希望文本输入仅接受数字序列。任何其他字符都应静默忽略。这是我组件的简化版本:
<template>
<div id="app">
<input :value="tel" @input="setTel" placeholder="only numbers" />
<p>{{ tel }}</p>
</div>
</template>
<script>
export default {
name: "App",
data: () => ({
tel: "1234"
}),
methods: {
setTel(v) {
const val = v.target.value.replace(/[^0-9]/g, "");
this.tel = val;
/*this.tel = v.target.value = v.target.value.replace(/[^0-9]/g, "");*/
}
}
};
</script>
在React中,有controlled components的概念,但是在Vue中似乎没有什么相似之处。
我发现的解决方法(您可以在注释中看到)是手动修改输入元素的值,但这有点违反了使用Vue的目的。
我也尝试使用v-model
,但问题仍然存在。
答案 0 :(得分:1)
<template>
<div id="app">
<input v-model="tel" v-on:keyup="setTel" placeholder="only numbers" />
<p>{{ tel }}</p>
</div>
</template>
<script>
export default {
name: "App",
data: () => ({
tel: "1234"
}),
methods: {
setTel(v) {
const val = v.target.value.replace(/[^0-9]/g, "");
this.tel = val;
/*this.tel = v.target.value = v.target.value.replace(/[^0-9]/g, "");*/
}
}
};
</script>
我查看了您的沙箱并进行了一些修改,请检查是否满足您的要求,视图现已更新。
答案 1 :(得分:1)
好吧,您可以像在这里所说的每个人一样使用<input type=number...
,但是如果您想手动处理,则可以在
<template>
<div id="app">
<input
:value="tel"
@input="setTel"
placeholder="0"
/>
<p>{{ tel }}</p>
</div>
</template>
<script>
export default {
name: "App",
data: () => ({
tel: "1234"
}),
methods: {
setTel(v) {
v.target.value = v.target.value.replace(/[^0-9]/g, "");
this.tel = v.target.value
/*this.tel = v.target.value = v.target.value.replace(/[^0-9]/g, "");*/
}
}
};
</script>
对于vue在输入中显示文本的部分,是因为当您在替换文本后分配相同的值时,vue不会刷新该特定元素的状态以避免额外的渲染
答案 2 :(得分:1)
您应该处理keyup
,而不是处理keydown
(这将允许密钥到达输入)。处理程序应调用event.preventDefault()
和event.stopPropagation()
来忽略密钥:
// ignore non-numeric keys
if (!/\d/.test(v.key)) {
v.preventDefault()
v.stopPropagation()
return false
}
输入应允许使用元键(例如允许复制粘贴或删除):
// allow all meta keys (including Backspace) to pass through
if (v.metaKey || /(Backspace|Meta)/g.test(v.key)) {
console.log('ignoring', v.key)
return
}
此外,此输入应处理input
事件,以便过滤复制粘贴的值。
// template
<input v-model="tel" @input="onInput" v-on:keydown="setTel" />
// script
onInput(e) {
if (e.inputType !== 'insertText' && /[^0-9]/g.test(e.target.value)) {
const val = e.target.value.replace(/[^0-9]/g, "");
this.tel = val;
e.preventDefault()
e.stopPropagation()
return false
}
}
答案 3 :(得分:0)
您可以做几件事:
<input type=number
。这将阻止用户输入除数字以外的任何字符。这由浏览器处理。v-model
并添加一个侦听器@change
来检查值并相应地修改模型。您可以在模型上添加number
修饰符的节点,以便vue将输入转换为数字`
答案 4 :(得分:0)
您通过使用“替代方法”在输入上设置值来回答了自己的问题。 如果您希望它像React Controlled Components一样工作,则可以将目标输入的值设置为数据模型中的值,除非它实际上更改了数据模型。通过这种方式,Vue数据模型将成为您唯一的真理来源。
<template>
<div id="app">
<input
v-bind:value="tel"
v-on:input="handleInputTel"
placeholder="only numbers"
/>
<p>{{ tel }}</p>
</div>
</template>
<script>
export default {
name: "App",
data: () => ({
tel: "1234"
}),
methods: {
handleInputTel(v) {
if (validate(v.target.value)) this.tel = v.target.value;
else v.target.value = this.tel;
}
}
};
</script>
答案 5 :(得分:0)
因为VUE的渲染策略,如果状态和old没有区别,这个输入组件不会重新渲染。但是输入 DOM 发生了变化。 因此,您可以在输入事件上使用 $forceUpdate。
setTel(v) {
const val = v.target.value.replace(/[^0-9]/g, "");
this.tel = val;
this.$forceUpdate();
}