基于Is there specific number input component in Vuetify?,我尝试创建一个数字输入。
输入和输出值为unknown
,因此可能为undefined
或null
,因为可能需要清除该字段,因此它不应响应0
。
如果可能,输入组件不应有"向上"/"向下"按钮。
如果用户传入一个标记isAcceptingFloatingPointNumbers = false
,则此输入应仅接受整数值(不应输入浮点数)
生殖环节
<template>
<v-app>
<v-main>
<v-text-field
type="number"
label="number input"
:clearable="true"
:model-value="num"
@update:modelValue="num = $event"
/>
</v-main>
</v-app>
</template>
<script setup lang="ts">
import { ref, watch, Ref } from 'vue'
const num: Ref<unknown> = ref(undefined)
watch(num, () => console.log(num.value))
</script>
如果标志isAcceptingFloatingPointNumbers
返回false
,我如何确保用户只能键入整数值?我想到的唯一方法是附加一个自定义规则,如
v => Number.isInteger(v) || 'Must be integer'
但是AFAIK即使值可以是undefined
,此规则也会触发。是否有办法阻止用户输入?
基于yoduh's answer我尝试了这个(复制链接)
NumberField.vue
<template>
<v-text-field
type="number"
label="number input"
:clearable="true"
:model-value="num"
@update:modelValue="emit('update:modelValue', $event)"
@keypress="filterInput"
/>
</template>
<script setup lang="ts">
const props = defineProps<{
num: unknown;
isAcceptingFloatingPointNumbers: boolean;
}>();
const emit = defineEmits<{
(e: "update:modelValue", newValue: unknown): void;
}>();
function filterInput(inputEvent) {
if(props.isAcceptingFloatingPointNumbers.value) {
return true;
}
const inputAsString = inputEvent.target.value.toString() + inputEvent.key.toString();
const inputValue = Number(inputAsString);
if(!Number.isInteger(inputValue)) {
inputEvent.preventDefault();
}
return true;
}
</script>
我像这样消耗组件
<template>
<number-field :num="num" :isAcceptingFloatingPointNumbers="false" @update:model-value="num = $event" />
</template>
<script setup lang="ts">
import { ref, watch } from 'vue'
import NumberField from "./NumberField.vue";
const num: Ref<unknown> = ref(undefined);
watch(num, () => console.log(num.value));
</script>
问题是我的过滤函数出错了,仍然可以输入"12.4",因为过滤器忽略了"12.",然后将"12.4"转换为124。
有人知道怎么解决吗?
4条答案
按热度按时间l7mqbcuq1#
由于整数只由数字组成,因此您可以只测试每个按下的键是否为数字,而无需检查整个输入值。
关于箭头,它不是Vuetify特定的元素,而是浏览器添加到类型编号输入的元素。您可以禁用它们like this。
bis0qfac2#
据我所知,您有以下要求**:**
isAcceptingFloatingPointNumbers
标志值输入(如果标志为false
,则仅接受整数,否则字段应接受浮点数)。0
值。如果我上面的理解是正确的,你可以简单地通过正常的文本字段和每个
keyup
事件实现这个要求,你可以用一个空字符串替换输入值,如果它不匹配传递有效的regEx
.现场演示**:**
yiytaume3#
我认为最好的方法是创建一个自定义的过滤器函数,在按键时运行。使用你自己的自定义过滤器,你也可以删除
type="number"
,因为它不再是必要的,并将删除输入上的向上/向下箭头。更新沙箱
djp7away4#
根据您对@yoduh答案的评论,如果您想坚持使用
type="number"
(有利于减少验证非数字字符的步骤),则使用以下CSS隐藏箭头-逻辑1-
keyup
事件中,检查isAcceptingFloatingPointNumbers
是否为false且键入的输入是否为整数,清空输入字段的值。**要检查输入值是否为整数-1.您可以使用正则表达式模式
/^-?[0-9]+$/.test(num)
。1.您可以使用JS方法
Number.isInteger(num)
。但是,在第二种方法中,输入值的类型总是string(why?),要解决这个问题,请使用内置的Vue.js指令
v-model.number
将输入值的类型重新转换为数字。演示-
x一个一个一个一个x一个一个二个一个x一个一个三个一个
这里唯一的问题是,如果用户键入
123.
并停止键入,那么dot
将可见,因为type="number"
,但如果您使用此值,它将始终被解码为123
。如果要限制
dot
的类型,请检测keypress
事件上的键并阻止进一步执行。编辑-------------
逻辑2
如果用户尝试输入浮点数,则可以使用Math.trunc(num)方法删除小数位,返回该浮点数的整数部分。
演示-