InputNumber

数字字段GitHub
一个用于输入数值并可自定义范围的输入组件。

用法

使用 v-model 指令来控制 InputNumber 的值。

<script setup lang="ts">
const value = ref(5)
</script>

<template>
  <UInputNumber v-model="value" />
</template>

使用 default-value prop 在您不需要控制其状态时设置初始值。

<template>
  <UInputNumber :default-value="5" />
</template>
此组件依赖于@internationalized/number该软件包提供了跨语言环境和计数系统格式化及解析数字的实用程序。

最小值 / 最大值

使用 minmax 属性来设置 InputNumber 的最小值和最大值。

<script setup lang="ts">
const value = ref(5)
</script>

<template>
  <UInputNumber v-model="value" :min="0" :max="10" />
</template>

步长

使用 step 属性来设置 InputNumber 的步长值。

<script setup lang="ts">
const value = ref(5)
</script>

<template>
  <UInputNumber v-model="value" :step="2" />
</template>

Orientation

使用 orientation 属性来更改 InputNumber 的方向。

<script setup lang="ts">
const value = ref(5)
</script>

<template>
  <UInputNumber v-model="value" orientation="vertical" />
</template>

占位符

使用 placeholder 属性设置占位文本。

<template>
  <UInputNumber placeholder="Enter a number" />
</template>

颜色

使用 color 属性来更改 InputNumber 获取焦点时的环形颜色。

<script setup lang="ts">
const value = ref(5)
</script>

<template>
  <UInputNumber v-model="value" color="neutral" highlight />
</template>

变体

使用 variant 属性来更改 InputNumber 的变体样式。

<script setup lang="ts">
const value = ref(5)
</script>

<template>
  <UInputNumber v-model="value" variant="subtle" color="neutral" />
</template>

尺寸

使用 size 属性来更改 InputNumber 的尺寸。

<script setup lang="ts">
const value = ref(5)
</script>

<template>
  <UInputNumber v-model="value" size="xl" />
</template>

禁用

使用 disabled 属性来禁用 InputNumber。

<script setup lang="ts">
const value = ref(5)
</script>

<template>
  <UInputNumber v-model="value" disabled />
</template>

递增 / 递减

使用 incrementdecrement 属性,通过任何 Button 属性来自定义递增和递减按钮。默认值为 { variant: 'link' }

<script setup lang="ts">
const value = ref(5)
</script>

<template>
  <UInputNumber
    v-model="value"
    :increment="{
      color: 'neutral',
      variant: 'solid',
      size: 'xs'
    }"
    :decrement="{
      color: 'neutral',
      variant: 'solid',
      size: 'xs'
    }"
  />
</template>

递增 / 递减图标

使用 increment-icondecrement-icon 属性来自定义按钮的 图标。默认值为 i-lucide-plus / i-lucide-minus

<script setup lang="ts">
const value = ref(5)
</script>

<template>
  <UInputNumber
    v-model="value"
    increment-icon="i-lucide-arrow-right"
    decrement-icon="i-lucide-arrow-left"
  />
</template>

示例

使用小数格式

使用 format-options 属性来自定义数值的格式。

<script setup lang="ts">
const value = ref(5)
</script>

<template>
  <UInputNumber
    v-model="value"
    :format-options="{
      signDisplay: 'exceptZero',
      minimumFractionDigits: 1
    }"
  />
</template>

使用百分比格式

使用带有 style: 'percent'format-options 属性来自定义数值格式。

<script setup lang="ts">
const value = ref(0.05)
</script>

<template>
  <UInputNumber
    v-model="value"
    :step="0.01"
    :format-options="{
      style: 'percent'
    }"
  />
</template>

使用货币格式

使用带有 style: 'currency'format-options 属性来自定义数值格式。

<script setup lang="ts">
const value = ref(1500)
</script>

<template>
  <UInputNumber
    v-model="value"
    :format-options="{
      style: 'currency',
      currency: 'EUR',
      currencyDisplay: 'code',
      currencySign: 'accounting'
    }"
  />
</template>

不带按钮

您可以使用 incrementdecrement 属性来控制按钮的显示。

<script setup lang="ts">
const value = ref(5)
</script>

<template>
  <UInputNumber
    v-model="value"
    :increment="false"
    :decrement="false"
  />
</template>

在 FormField 中

您可以在 FormField 组件中使用 InputNumber,以显示标签、帮助文本、必填指示器等。

指定尝试次数
<script setup lang="ts">
const retries = ref(0)
</script>

<template>
  <UFormField label="Retries" help="Specify number of attempts" required>
    <UInputNumber v-model="retries" placeholder="Enter retries" />
  </UFormField>
</template>

使用插槽

使用 #increment#decrement 插槽来自定义按钮。

<script setup lang="ts">
const value = ref(5)
</script>

<template>
  <UInputNumber v-model="value">
    <template #decrement>
      <UButton size="xs" icon="i-lucide-minus" />
    </template>

    <template #increment>
      <UButton size="xs" icon="i-lucide-plus" />
    </template>
  </UInputNumber>
</template>

API

属性

属性默认值类型
as'div'any

此组件应渲染为的元素或组件。

placeholderstring

输入为空时的占位文本。

color'primary'"primary" | "secondary" | "success" | "info" | "warning" | "error" | "neutral"
variant'outline'"outline" | "soft" | "subtle" | "ghost" | "none"
尺寸'md'"xs" | "sm" | "md" | "lg" | "xl"
高亮boolean

高亮环形颜色,如同焦点状态。

fixedboolean

在所有断点处保持移动端文本大小。

orientation'horizontal'"horizontal" | "vertical"

数字输入的排列方向。

incrementtrueboolean | Omit<ButtonProps, LinkPropsKeys>

配置递增按钮。colorsize 会被继承。

incrementIconappConfig.ui.icons.plusany

用于递增数值的图标。

incrementDisabledboolean

禁用递增按钮。

decrementtrueboolean | Omit<ButtonProps, LinkPropsKeys>

配置递减按钮。colorsize 会被继承。

decrementIconappConfig.ui.icons.minusany

用于递减数值的图标。

decrementDisabledboolean

禁用递减按钮。

autofocusboolean
autofocusDelaynumber
defaultValueNonNullable<T>
modelValueT | Mod extends { optional: true; } ? undefined : never
modelModifiersMod
最小值number

输入允许的最小值。

maxnumber

输入允许的最大值。

stepnumber

每次点击递增或递减时输入值变化的量。

stepSnappingboolean

当为 false 时,防止数值吸附到最接近的步长倍数。

disabledboolean

当为 true 时,防止用户与数字字段进行交互。

requiredboolean

当为 true 时,表示用户必须在提交所属表单之前设置值。

idstring

元素的 ID

namestring

字段的名称。作为名称/值对的一部分随其所属表单提交。

formatOptionsIntl.NumberFormatOptions

数字字段中显示值的格式化选项。这也会影响允许用户键入的字符。

disableWheelChangeboolean

当为 true 时,防止通过鼠标滚轮滚动更改数值。

invertWheelChangeboolean

当为 true 时,反转滚轮更改的方向。

readonlyboolean

当为 true 时,数字字段为只读状态。

focusOnChangeboolean

当为 true 时,输入框将在值更改时自动获取焦点。

liststring
autocomplete"on" | "off" | string & {}
ui{ root?: ClassNameValue; base?: ClassNameValue; increment?: ClassNameValue; decrement?: ClassNameValue; }
此组件还支持所有原生 <input> HTML 属性。

插槽

插槽类型
increment{}
decrement{}

事件

事件类型
update:modelValue[value: ApplyModifiers<T, Mod>]
blur[事件: FocusEvent]
change[事件: Event]

可访问属性

通过模板引用访问组件时,您可以使用以下内容:

名称类型
inputRefRef<HTMLInputElement | null>

主题

app.config.ts
export default defineAppConfig({
  ui: {
    inputNumber: {
      slots: {
        root: 'relative inline-flex items-center',
        base: [
          'w-full rounded-md border-0 placeholder:text-dimmed focus:outline-none disabled:cursor-not-allowed disabled:opacity-75',
          'transition-colors'
        ],
        increment: 'absolute flex items-center',
        decrement: 'absolute flex items-center'
      },
      variants: {
        fieldGroup: {
          horizontal: {
            root: 'group has-focus-visible:z-[1]',
            base: 'group-not-only:group-first:rounded-e-none group-not-only:group-last:rounded-s-none group-not-last:group-not-first:rounded-none'
          },
          vertical: {
            root: 'group has-focus-visible:z-[1]',
            base: 'group-not-only:group-first:rounded-b-none group-not-only:group-last:rounded-t-none group-not-last:group-not-first:rounded-none'
          }
        },
        color: {
          primary: '',
          secondary: '',
          success: '',
          info: '',
          warning: '',
          error: '',
          neutral: ''
        },
        size: {
          xs: 'px-2 py-1 text-sm/4 gap-1',
          sm: 'px-2.5 py-1.5 text-sm/4 gap-1.5',
          md: 'px-2.5 py-1.5 text-base/5 gap-1.5',
          lg: 'px-3 py-2 text-base/5 gap-2',
          xl: 'px-3 py-2 text-base gap-2'
        },
        variant: {
          outline: 'text-highlighted bg-default ring ring-inset ring-accented',
          soft: 'text-highlighted bg-elevated/50 hover:bg-elevated focus:bg-elevated disabled:bg-elevated/50',
          subtle: 'text-highlighted bg-elevated ring ring-inset ring-accented',
          ghost: 'text-highlighted bg-transparent hover:bg-elevated focus:bg-elevated disabled:bg-transparent dark:disabled:bg-transparent',
          none: 'text-highlighted bg-transparent'
        },
        disabled: {
          true: {
            increment: 'opacity-75 cursor-not-allowed',
            decrement: 'opacity-75 cursor-not-allowed'
          }
        },
        orientation: {
          horizontal: {
            base: 'text-center',
            increment: 'inset-y-0 end-0 pe-1',
            decrement: 'inset-y-0 start-0 ps-1'
          },
          vertical: {
            increment: 'top-0 end-0 pe-1 [&>button]:py-0 scale-80',
            decrement: 'bottom-0 end-0 pe-1 [&>button]:py-0 scale-80'
          }
        },
        highlight: {
          true: ''
        },
        fixed: {
          false: ''
        },
        increment: {
          false: ''
        },
        decrement: {
          false: ''
        }
      },
      compoundVariants: [
        {
          color: 'primary',
          variant: [
            'outline',
            'subtle'
          ],
          class: 'focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-primary'
        },
        {
          color: 'primary',
          highlight: true,
          class: 'ring ring-inset ring-primary'
        },
        {
          color: 'neutral',
          variant: [
            'outline',
            'subtle'
          ],
          class: 'focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-inverted'
        },
        {
          color: 'neutral',
          highlight: true,
          class: 'ring ring-inset ring-inverted'
        },
        {
          orientation: 'horizontal',
          decrement: false,
          class: 'text-start'
        },
        {
          decrement: true,
          size: 'xs',
          class: 'ps-7'
        },
        {
          decrement: true,
          size: 'sm',
          class: 'ps-8'
        },
        {
          decrement: true,
          size: 'md',
          class: 'ps-9'
        },
        {
          decrement: true,
          size: 'lg',
          class: 'ps-10'
        },
        {
          decrement: true,
          size: 'xl',
          class: 'ps-11'
        },
        {
          increment: true,
          size: 'xs',
          class: 'pe-7'
        },
        {
          increment: true,
          size: 'sm',
          class: 'pe-8'
        },
        {
          increment: true,
          size: 'md',
          class: 'pe-9'
        },
        {
          increment: true,
          size: 'lg',
          class: 'pe-10'
        },
        {
          increment: true,
          size: 'xl',
          class: 'pe-11'
        },
        {
          fixed: false,
          size: 'xs',
          class: 'md:text-xs'
        },
        {
          fixed: false,
          size: 'sm',
          class: 'md:text-xs'
        },
        {
          fixed: false,
          size: 'md',
          class: 'md:text-sm'
        },
        {
          fixed: false,
          size: 'lg',
          class: 'md:text-sm'
        }
      ],
      defaultVariants: {
        size: 'md',
        color: 'primary',
        variant: 'outline'
      }
    }
  }
})
vite.config.ts
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import ui from '@nuxt/ui/vite'

export default defineConfig({
  plugins: [
    vue(),
    ui({
      ui: {
        inputNumber: {
          slots: {
            root: 'relative inline-flex items-center',
            base: [
              'w-full rounded-md border-0 placeholder:text-dimmed focus:outline-none disabled:cursor-not-allowed disabled:opacity-75',
              'transition-colors'
            ],
            increment: 'absolute flex items-center',
            decrement: 'absolute flex items-center'
          },
          variants: {
            fieldGroup: {
              horizontal: {
                root: 'group has-focus-visible:z-[1]',
                base: 'group-not-only:group-first:rounded-e-none group-not-only:group-last:rounded-s-none group-not-last:group-not-first:rounded-none'
              },
              vertical: {
                root: 'group has-focus-visible:z-[1]',
                base: 'group-not-only:group-first:rounded-b-none group-not-only:group-last:rounded-t-none group-not-last:group-not-first:rounded-none'
              }
            },
            color: {
              primary: '',
              secondary: '',
              success: '',
              info: '',
              warning: '',
              error: '',
              neutral: ''
            },
            size: {
              xs: 'px-2 py-1 text-sm/4 gap-1',
              sm: 'px-2.5 py-1.5 text-sm/4 gap-1.5',
              md: 'px-2.5 py-1.5 text-base/5 gap-1.5',
              lg: 'px-3 py-2 text-base/5 gap-2',
              xl: 'px-3 py-2 text-base gap-2'
            },
            variant: {
              outline: 'text-highlighted bg-default ring ring-inset ring-accented',
              soft: 'text-highlighted bg-elevated/50 hover:bg-elevated focus:bg-elevated disabled:bg-elevated/50',
              subtle: 'text-highlighted bg-elevated ring ring-inset ring-accented',
              ghost: 'text-highlighted bg-transparent hover:bg-elevated focus:bg-elevated disabled:bg-transparent dark:disabled:bg-transparent',
              none: 'text-highlighted bg-transparent'
            },
            disabled: {
              true: {
                increment: 'opacity-75 cursor-not-allowed',
                decrement: 'opacity-75 cursor-not-allowed'
              }
            },
            orientation: {
              horizontal: {
                base: 'text-center',
                increment: 'inset-y-0 end-0 pe-1',
                decrement: 'inset-y-0 start-0 ps-1'
              },
              vertical: {
                increment: 'top-0 end-0 pe-1 [&>button]:py-0 scale-80',
                decrement: 'bottom-0 end-0 pe-1 [&>button]:py-0 scale-80'
              }
            },
            highlight: {
              true: ''
            },
            fixed: {
              false: ''
            },
            increment: {
              false: ''
            },
            decrement: {
              false: ''
            }
          },
          compoundVariants: [
            {
              color: 'primary',
              variant: [
                'outline',
                'subtle'
              ],
              class: 'focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-primary'
            },
            {
              color: 'primary',
              highlight: true,
              class: 'ring ring-inset ring-primary'
            },
            {
              color: 'neutral',
              variant: [
                'outline',
                'subtle'
              ],
              class: 'focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-inverted'
            },
            {
              color: 'neutral',
              highlight: true,
              class: 'ring ring-inset ring-inverted'
            },
            {
              orientation: 'horizontal',
              decrement: false,
              class: 'text-start'
            },
            {
              decrement: true,
              size: 'xs',
              class: 'ps-7'
            },
            {
              decrement: true,
              size: 'sm',
              class: 'ps-8'
            },
            {
              decrement: true,
              size: 'md',
              class: 'ps-9'
            },
            {
              decrement: true,
              size: 'lg',
              class: 'ps-10'
            },
            {
              decrement: true,
              size: 'xl',
              class: 'ps-11'
            },
            {
              increment: true,
              size: 'xs',
              class: 'pe-7'
            },
            {
              increment: true,
              size: 'sm',
              class: 'pe-8'
            },
            {
              increment: true,
              size: 'md',
              class: 'pe-9'
            },
            {
              increment: true,
              size: 'lg',
              class: 'pe-10'
            },
            {
              increment: true,
              size: 'xl',
              class: 'pe-11'
            },
            {
              fixed: false,
              size: 'xs',
              class: 'md:text-xs'
            },
            {
              fixed: false,
              size: 'sm',
              class: 'md:text-xs'
            },
            {
              fixed: false,
              size: 'md',
              class: 'md:text-sm'
            },
            {
              fixed: false,
              size: 'lg',
              class: 'md:text-sm'
            }
          ],
          defaultVariants: {
            size: 'md',
            color: 'primary',
            variant: 'outline'
          }
        }
      }
    })
  ]
})
为便于阅读,compoundVariants 中的某些颜色已省略。请在 GitHub 上查看源代码。

更新日志

v4.5.0
  • 8f5f4— fix(components): 添加 fixed 属性以防止响应式文本尺寸减小 (#6074)
  • cd343— fix(components): 支持可空 (nullable) 和可选 (optional) 类型 (#6060)
  • 12620— fix(components): 防止 iOS 在字体大小低于 16px 的输入框上自动缩放 (#6040)
  • c9704— feat(Theme): 新组件 (#4387)
  • 053f3— chore(deps): 更新依赖 reka-ui 到 v2.8.0 (v4) (#5969)
  • 1ec16— fix(InputMenu/InputNumber/SelectMenu): 将 size 代理到按钮
v4.4.0
  • 55646— feat(components): 添加 valueKey 属性 (#5905)
v4.3.0
  • 184ea— chore(components): 通过省略操作按钮的链接属性来减少类型的冗余
v4.2.0
  • dd81d— feat(components): 添加 data-slot 属性 (#5447)
  • a6efa— fix(components): 移除 locale / dir 属性代理 (#5432)
  • fda3c— fix(components): 清理 HTML 属性扩展
  • 5b177— feat(components): 扩展原生 HTML 属性 (#5348)
  • fce2d— fix(components)!: 统一暴露的 refs (#5385)
  • 5c347— fix(Input/InputNumber/Textarea): 将 modelModifiers 设为泛型 (#5361)
v4.1.0
  • 18589— feat(InputNumber): 将 increment / decrement 作为布尔值处理 (#4805)
v4.0.0
  • 83b03— feat(components)!: 将 nullify 修饰符重命名为 nullable 并添加 optional (#4838)
v3.3.4
  • 11a03— fix(components): labelKeyvalueKey 支持点符号类型 (#4933)
v3.3.3
  • 7133f— fix(components): 修复 update:model-value 事件的类型错误 (#4853)
  • 61b60— feat(Icon): 允许传递组件而非名称 (#4766)
v3.3.1
  • a0963— feat(FieldGroup)!: 从 ButtonGroup 更名 (#4596)
  • 5cb65— feat: 导入 @nuxt/ui-pro 组件 (#4675)
  • ee484— chore(deps): 更新依赖 reka-ui 到 v2.4.1 (v3) (#4586)
v3.3.0
  • 6f2ce— refactor(components): 统一事件 (emits) 声明语法 (#4512)
v3.2.0
  • f7613— chore(deps): 更新依赖 reka-ui 至 ^2.3.0 (v3) (#4234)
v3.1.2
  • 2e4c3— fix(InputNumber): 处理按钮组内部的情况
  • c7fba— feat(InputNumber): 添加 increment-disabled / decrement-disabled 属性 (#4141)
  • e6e51— fix(components): class 应优先于 ui 属性
v3.1.0
  • d49e0— feat(module): 定义中性效用类 (neutral utilities) (#3629)
  • f9737— feat(module): 动态 rounded-* 工具类 (#3906)
  • 39c86— fix(components): 在 @nuxt/module-builder 升级后重构类型 (#3855)
  • 4d817— chore(Input/InputNumber/PinInput/Textarea): 清理函数顺序
  • f5e62— feat(InputNumber): 添加对 stepSnappingdisableWheelChange 属性的支持 (#3731)