输入数值,范围可自定义。
此组件依赖于@internationalized/number包,该包提供了跨区域设置和编号系统格式化和解析数字的工具。

用法

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

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

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

当您不需要控制其状态时,使用 default-value 属性设置初始值。

<template>
  <UInputNumber :default-value="5" />
</template>

最小值 / 最大值

使用 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 属性更改 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>

在 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

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

placeholder

string

输入为空时的占位文本。

color

'primary'

"error" | "primary" | "secondary" | "success" | "info" | "warning" | "neutral"

variant

'outline'

"outline" | "soft" | "subtle" | "ghost" | "none"

size

'md'

"sm" | "md" | "xs" | "lg" | "xl"

highlight

boolean

像焦点状态一样高亮外环颜色。

orientation

'horizontal'

"horizontal" | "vertical"

输入菜单的方向。

increment

{ variant: 'link' }

ButtonProps

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

incrementIcon

appConfig.ui.icons.plus

string

用于增加值的图标。

递减

{ variant: 'link' }

ButtonProps

配置递减按钮。继承 colorsize 属性。

decrementIcon

appConfig.ui.icons.minus

string

用于减少值的图标。

autofocus

boolean

autofocusDelay

number

locale

UApp.locale.code

string

用于格式化和解析数字的区域设置。

disabled

boolean

true 时,阻止用户与 Number Field 交互。

name

string

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

modelValue

null | number

defaultValue

number

required

boolean

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

id

string

元素的 ID

min

number

输入允许的最小值。

max

number

输入允许的最大值。

step

number

输入值在每次增加或减少“tick”时变化的量。

stepSnapping

boolean

false 时,阻止值吸附到步进值的最近增量。

formatOptions

NumberFormatOptions

显示在 Number Field 中的值的格式化选项。这也影响用户可以输入的字符。

disableWheelChange

boolean

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

ui

{ root?: ClassNameValue; base?: ClassNameValue; increment?: ClassNameValue; decrement?: ClassNameValue; }

插槽

插槽类型
increment

{}

递减

{}

事件

事件类型
blur

[event?: FocusEvent]

change

[payload?: Event]

update:modelValue

[payload?: number]

暴露

当通过模板引用(template ref)访问组件时,可以使用以下属性:

名称类型
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: {
        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: ''
        }
      },
      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',
          size: 'xs',
          class: 'px-7'
        },
        {
          orientation: 'horizontal',
          size: 'sm',
          class: 'px-8'
        },
        {
          orientation: 'horizontal',
          size: 'md',
          class: 'px-9'
        },
        {
          orientation: 'horizontal',
          size: 'lg',
          class: 'px-10'
        },
        {
          orientation: 'horizontal',
          size: 'xl',
          class: 'px-11'
        },
        {
          orientation: 'vertical',
          size: 'xs',
          class: 'pe-7'
        },
        {
          orientation: 'vertical',
          size: 'sm',
          class: 'pe-8'
        },
        {
          orientation: 'vertical',
          size: 'md',
          class: 'pe-9'
        },
        {
          orientation: 'vertical',
          size: 'lg',
          class: 'pe-10'
        },
        {
          orientation: 'vertical',
          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: {
            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: ''
            }
          },
          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',
              size: 'xs',
              class: 'px-7'
            },
            {
              orientation: 'horizontal',
              size: 'sm',
              class: 'px-8'
            },
            {
              orientation: 'horizontal',
              size: 'md',
              class: 'px-9'
            },
            {
              orientation: 'horizontal',
              size: 'lg',
              class: 'px-10'
            },
            {
              orientation: 'horizontal',
              size: 'xl',
              class: 'px-11'
            },
            {
              orientation: 'vertical',
              size: 'xs',
              class: 'pe-7'
            },
            {
              orientation: 'vertical',
              size: 'sm',
              class: 'pe-8'
            },
            {
              orientation: 'vertical',
              size: 'md',
              class: 'pe-9'
            },
            {
              orientation: 'vertical',
              size: 'lg',
              class: 'pe-10'
            },
            {
              orientation: 'vertical',
              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 uiPro from '@nuxt/ui-pro/vite'

export default defineConfig({
  plugins: [
    vue(),
    uiPro({
      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: {
            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: ''
            }
          },
          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',
              size: 'xs',
              class: 'px-7'
            },
            {
              orientation: 'horizontal',
              size: 'sm',
              class: 'px-8'
            },
            {
              orientation: 'horizontal',
              size: 'md',
              class: 'px-9'
            },
            {
              orientation: 'horizontal',
              size: 'lg',
              class: 'px-10'
            },
            {
              orientation: 'horizontal',
              size: 'xl',
              class: 'px-11'
            },
            {
              orientation: 'vertical',
              size: 'xs',
              class: 'pe-7'
            },
            {
              orientation: 'vertical',
              size: 'sm',
              class: 'pe-8'
            },
            {
              orientation: 'vertical',
              size: 'md',
              class: 'pe-9'
            },
            {
              orientation: 'vertical',
              size: 'lg',
              class: 'pe-10'
            },
            {
              orientation: 'vertical',
              size: 'xl',
              class: 'pe-11'
            }
          ],
          defaultVariants: {
            size: 'md',
            color: 'primary',
            variant: 'outline'
          }
        }
      }
    })
  ]
})
为便于阅读,省略了 compoundVariants 中的一些颜色。请在 GitHub 上查看源代码。