返回

最大值谜团:v-input-number 超出限制时的奇异行为

前端

一个悲伤的故事

在 Vue.js 开发中,<v-input-number> 组件是一个数字输入框,它允许用户输入和编辑数字值。为了防止用户输入超出预期的值,我们可以使用 max 属性设置最大值。

然而,最近我遇到了一个奇怪的问题:当用户输入超出最大值时,<v-input-number> 组件的行为并不是我预期的。

v-input-number 的谜团

为了重现这个问题,我创建了一个简单的代码段:

<template>
  <v-input-number v-model="value" :max="1000"></v-input-number>
</template>

<script>
export default {
  data() {
    return {
      value: null,
    };
  },
};
</script>

如果我输入的值在最大值 1000 以内,组件的行为正常。但是,如果我输入 9999,即比最大值大一位,会出现一个奇怪的现象。

诡异的行为

当我在输入框中输入 9999 时,它会显示为 1000。然而,当我将焦点从输入框移开时,它会立即变回 9999。这表明组件内部正在发生一些我不知道的事情。

深入探究

为了弄清楚原因,我使用 Vue Devtools 检查了组件的状态。我发现,当输入值超出最大值时,组件的 value 属性被设置为 NaN(非数字)。

这解释了组件行为的奇怪之处:

  • 当焦点在输入框内时,组件显示的是 value 属性的字符串表示,即 "9999"。
  • 当焦点移开时,组件会对 value 属性执行一些验证。由于 NaN 不是一个有效的数字,因此它被重置为 null,这是最大值 1000 之前允许的唯一空值。

解决方案

解决此问题的最佳方法是使用 v-modelnumber 修饰符。此修饰符强制 value 属性始终为数字,从而防止出现 NaN 值。

<template>
  <v-input-number v-model.number="value" :max="1000"></v-input-number>
</template>

替代方案

如果无法使用 v-model.number 修饰符,另一种方法是使用 Vue 的 computed 属性手动验证输入值。

<template>
  <v-input-number v-model="value" :max="1000"></v-input-number>
</template>

<script>
export default {
  data() {
    return {
      value: null,
    };
  },
  computed: {
    validatedValue() {
      const num = Number(this.value);
      return isNaN(num) || num > this.max ? this.max : num;
    },
  },
};
</script>

结论

<v-input-number> 组件在处理超出最大值的输入时存在一个意外的行为。通过使用 v-model.number 修饰符或手动验证输入值,我们可以避免此问题,确保组件正常工作。