InputNumber

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

用法

使用 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 属性自定义按钮 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>

带百分比格式

使用 format-options 属性和 style: 'percent' 来自定义值的格式。

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

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

带货币格式

使用 format-options 属性和 style: 'currency' 来自定义值的格式。

<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

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

orientation'horizontal'"horizontal" | "vertical"

输入菜单的方向。

递增trueboolean | Omit<ButtonProps, LinkPropsKeys>

配置递增按钮。colorsize 是继承的。

incrementIconappConfig.ui.icons.plusany

显示用于递增值的图标。

incrementDisabledboolean

禁用递增按钮。

递减trueboolean | Omit<ButtonProps, LinkPropsKeys>

配置递减按钮。colorsize 是继承的。

decrementIconappConfig.ui.icons.minusany

显示用于递减值的图标。

decrementDisabledboolean

禁用递减按钮。

autofocusboolean
autofocusDelaynumber
modelModifiersPick<ModelModifiers<InputNumberValue>, "optional">
modelValuenull | number
defaultValuenumber
最小值number

输入允许的最小值。

maxnumber

输入允许的最大值。

stepnumber

输入值每次递增或递减“刻度”时的变化量。

stepSnappingboolean

false 时,阻止值自动对齐到最近的步长增量。

disabledboolean

true 时,阻止用户与数字输入框交互。

requiredboolean

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

idstring

元素的 ID

namestring

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

formatOptionsIntl.NumberFormatOptions

数字输入框中显示值的格式选项。这也影响用户可以输入的字符。

disableWheelChangeboolean

true 时,阻止值在滚轮滚动时改变。

invertWheelChangeboolean

true 时,反转滚轮改变的方向。

readonlyboolean

true 时,数字输入框为只读。

autocompletestring
liststring
ui{ root?: ClassNameValue; base?: ClassNameValue; increment?: ClassNameValue; decrement?: ClassNameValue; }
此组件还支持所有原生 <input> HTML 属性。

插槽

插槽类型
递增{}
递减{}

事件

事件类型
update:modelValue[value: InputNumberValue]
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-xs gap-1',
          sm: 'px-2.5 py-1.5 text-xs gap-1.5',
          md: 'px-2.5 py-1.5 text-sm gap-1.5',
          lg: 'px-3 py-2 text-sm 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: ''
        },
        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'
        }
      ],
      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-xs gap-1',
              sm: 'px-2.5 py-1.5 text-xs gap-1.5',
              md: 'px-2.5 py-1.5 text-sm gap-1.5',
              lg: 'px-3 py-2 text-sm 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: ''
            },
            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'
            }
          ],
          defaultVariants: {
            size: 'md',
            color: 'primary',
            variant: 'outline'
          }
        }
      }
    })
  ]
})
为便于阅读,compoundVariants 中的某些颜色已省略。请在 GitHub 上查看源代码。

更新日志

184ea— chore: 减少类型冗余,通过省略操作按钮中的链接属性

dd81d— feat: 添加 data-slot 属性 (#5447)

a6efa— fix: 移除 locale / dir props 代理 (#5432)

fda3c— 修复:清理 html 属性扩展

5b177— feat: 扩展原生 HTML 属性 (#5348)

fce2d— 修复!:一致的暴露引用 (#5385)

5c347— 修复:使 modelModifiers 泛型 (#5361)

18589— feat: 处理 increment / decrement 作为布尔值 (#4805)

11a03— fix: labelKeyvalueKey 的点表示法类型支持 (#4933)

83b03— feat!: 重命名 nullify 修饰符为 nullable 并添加 optional (#4838)

61b60— 功能:允许传递组件而不是名称 (#4766)

a0963— feat!: 重命名 ButtonGroup (#4596)

5cb65— 特性:导入 @nuxt/ui-pro 组件

7133f— 修复:update:model-value 事件类型错误 (#4853)

ee484— chore: 更新依赖 reka-ui 到 v2.4.1 (v3) (#4586)

6f2ce— 重构:统一 emits 声明的语法 (#4512)

f7613— chore:更新依赖 reka-ui 到 ^2.3.0 (v3)(#4234)

2e4c3— fix: 处理按钮组内部

c7fba— feat: 添加 increment-disabled / decrement-disabled 属性 (#4141)

e6e51— fix:class 应该优先于 ui 属性

39c86— fix:@nuxt/module-builder 升级后重构类型(#3855)

4d817— chore: 清理函数顺序

f5e62— feat: 添加对 stepSnappingdisableWheelChange 属性的支持 (#3731)