输入标签

显示交互式标记的输入元素。

用法

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

Vue
<script setup lang="ts">
const value = ref(['Vue'])
</script>

<template>
  <UInputTags v-model="value" />
</template>
<script setup lang="ts">
import { ref } from 'vue'

const value = ref(['Vue'])
</script>

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

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

Vue
<template>
  <UInputTags :default-value="['Vue']" />
</template>

占位符

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

<template>
  <UInputTags placeholder="Enter tags..." />
</template>

最大长度

使用max-length属性设置标记中允许的最大字符数。

<template>
  <UInputTags :max-length="4" />
</template>

Color

使用color属性更改InputTags聚焦时的环颜色。

Vue
<script setup lang="ts">
const value = ref(['Vue'])
</script>

<template>
  <UInputTags v-model="value" color="neutral" highlight />
</template>
<script setup lang="ts">
import { ref } from 'vue'

const value = ref(['Vue'])
</script>

<template>
  <UInputTags v-model="value" color="neutral" highlight />
</template>
这里使用highlight属性来显示焦点状态。当发生验证错误时,在内部使用它。

变体

使用variant属性更改InputTags的外观。

Vue
<script setup lang="ts">
const value = ref(['Vue'])
</script>

<template>
  <UInputTags v-model="value" variant="subtle" color="neutral" />
</template>
<script setup lang="ts">
import { ref } from 'vue'

const value = ref(['Vue'])
</script>

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

尺寸

使用size属性调整InputTags的大小。

Vue
<script setup lang="ts">
const value = ref(['Vue'])
</script>

<template>
  <UInputTags v-model="value" size="xl" />
</template>
<script setup lang="ts">
import { ref } from 'vue'

const value = ref(['Vue'])
</script>

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

Icon

使用icon prop在InputTags中显示Icon。

Vue
<script setup lang="ts">
const value = ref(['Vue'])
</script>

<template>
  <UInputTags v-model="value" icon="i-lucide-search" size="md" variant="outline" />
</template>
<script setup lang="ts">
import { ref } from 'vue'

const value = ref(['Vue'])
</script>

<template>
  <UInputTags v-model="value" icon="i-lucide-search" size="md" variant="outline" />
</template>
使用leading和trailing道具设置图标位置,或使用leading-icon和trailing-icon道具为每个位置设置不同的图标。

Avatar

使用avatar道具在InputTags中显示Avatar。

Vue
<script setup lang="ts">
const value = ref(['Vue'])
</script>

<template>
  <UInputTags
    v-model="value"
    :avatar="{
      src: 'https://github.com/vuejs.png',
      loading: 'lazy'
    }"
    size="md"
    variant="outline"
  />
</template>
<script setup lang="ts">
import { ref } from 'vue'

const value = ref(['Vue'])
</script>

<template>
  <UInputTags
    v-model="value"
    :avatar="{
      src: 'https://github.com/vuejs.png',
      loading: 'lazy'
    }"
    size="md"
    variant="outline"
  />
</template>

删除图标

使用delete-icon prop自定义删除标签中的Icon。

Vue
<script setup lang="ts">
const value = ref(['Vue'])
</script>

<template>
  <UInputTags v-model="value" delete-icon="i-lucide-trash" />
</template>
<script setup lang="ts">
import { ref } from 'vue'

const value = ref(['Vue'])
</script>

<template>
  <UInputTags v-model="value" delete-icon="i-lucide-trash" />
</template>
你可以在你的app.config.ts中的ui.icons.close键下全局自定义这个图标。
你可以在你的vite.config.ts下的ui.icons.close键全局自定义这个图标。

加载中

使用loading prop在InputTags上显示一个加载图标。

Vue
<script setup lang="ts">
const value = ref(['Vue'])
</script>

<template>
  <UInputTags v-model="value" loading />
</template>
<script setup lang="ts">
import { ref } from 'vue'

const value = ref(['Vue'])
</script>

<template>
  <UInputTags v-model="value" loading />
</template>

加载图标

使用loading-icon道具自定义加载图标. i-lucide-loader-circle。

Vue
<script setup lang="ts">
const value = ref(['Vue'])
</script>

<template>
  <UInputTags v-model="value" loading loading-icon="i-lucide-loader" />
</template>
<script setup lang="ts">
import { ref } from 'vue'

const value = ref(['Vue'])
</script>

<template>
  <UInputTags v-model="value" loading loading-icon="i-lucide-loader" />
</template>
你可以在你的app.config.ts中的ui.icons.loading键下全局自定义这个图标。
你可以在你的vite.config.ts下的ui.icons.loading键全局自定义这个图标。

禁用

使用disabled属性禁用InputTags。

Vue
<script setup lang="ts">
const value = ref(['Vue'])
</script>

<template>
  <UInputTags v-model="value" disabled />
</template>
<script setup lang="ts">
import { ref } from 'vue'

const value = ref(['Vue'])
</script>

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

示例

在表单域中

您可以使用FormField组件中的InputTags来显示标签、帮助文本、必需的指示符等。

Vue
<script setup lang="ts">
const tags = ref(['Vue'])
</script>

<template>
  <UFormField label="Tags" required>
    <UInputTags v-model="tags" placeholder="Enter tags..." />
  </UFormField>
</template>
<script setup lang="ts">
import { ref } from 'vue'

const tags = ref(['Vue'])
</script>

<template>
  <UFormField label="Tags" required>
    <UInputTags v-model="tags" placeholder="Enter tags..." />
  </UFormField>
</template>

API

Props

Prop Default Type
as
'div'
any

The element or component this component should render as.

placeholder
string

The placeholder text when the input is empty.

maxLength
number

The maximum number of character allowed.

color
'primary'
"primary" | "secondary" | "success" | "info" | "warning" | "error" | "neutral"
variant
'outline'
"outline" | "soft" | "subtle" | "ghost" | "none"
size
'md'
"xs" | "sm" | "md" | "lg" | "xl"
autofocus
boolean
autofocusDelay
0
number
deleteIcon
appConfig.ui.icons.close
any

The icon displayed to delete a tag.

highlight
boolean

Highlight the ring color like a focus state.

fixed
boolean

Keep the mobile text size on all breakpoints.

modelValue
null | T[]

The controlled value of the tags input. Can be bind as v-model.

defaultValue
T[]

The value of the tags that should be added. Use when you do not need to control the state of the tags input

addOnPaste
boolean

When true, allow adding tags on paste. Work in conjunction with delimiter prop.

addOnTab
boolean

When true allow adding tags on tab keydown

addOnBlur
boolean

When true allow adding tags blur input

duplicate
boolean

When true, allow duplicated tags.

disabled
boolean

When true, prevents the user from interacting with the tags input.

delimiter
string | RegExp

The character or regular expression to trigger the addition of a new tag. Also used to split tags for @paste event

max
number

Maximum number of tags.

id
string
convertValue
(value: string): T

Convert the input value to the desired type. Mandatory when using objects as values and using TagsInputInput

displayValue
(value: T): string

Display the value of the tag. Useful when you want to apply modifications to the value like adding a suffix or when using object as values

name
string

The name of the field. Submitted with its owning form as part of a name/value pair.

required
boolean

When true, indicates that the user must set the value before the owning form can be submitted.

icon
any

Display an icon based on the leading and trailing props.

avatar
AvatarProps

Display an avatar on the left side.

leading
boolean

When true, the icon will be displayed on the left side.

leadingIcon
any

Display an icon on the left side.

trailing
boolean

When true, the icon will be displayed on the right side.

trailingIcon
any

Display an icon on the right side.

loading
boolean

When true, the loading icon will be displayed.

loadingIcon
appConfig.ui.icons.loading
any

The icon when the loading prop is true.

list
string
readonly
false | true | "true" | "false"
autocomplete
"on" | "off" | string
ui
{ root?: SlotClass; base?: SlotClass; leading?: SlotClass; leadingIcon?: SlotClass; leadingAvatar?: SlotClass; leadingAvatarSize?: SlotClass; trailing?: SlotClass; trailingIcon?: SlotClass; item?: SlotClass; itemText?: SlotClass; itemDelete?: SlotClass; itemDeleteIcon?: SlotClass; input?: SlotClass; }
此组件还支持所有原生<input> HTML属性。

Slots

Slot Type
leading
{ ui: object; }
default
{ ui: object; }
trailing
{ ui: object; }
item-text
{ item: T; index: number; ui: object; }
item-delete
{ item: T; index: number; ui: object; }

Emits

Event Type
change
[event: Event]
blur
[event: FocusEvent]
focus
[event: FocusEvent]
update:modelValue
[payload: T[]]
invalid
[payload: T]
addTag
[payload: T]
removeTag
[payload: T]

曝光

通过模板引用访问组件时,可以使用以下命令:

名称类型
inputRefRef<HTMLInputElement | null>

Theme

app.config.ts
export default defineAppConfig({
  ui: {
    inputTags: {
      slots: {
        root: [
          'relative inline-flex items-center',
          'flex-wrap'
        ],
        base: [
          'rounded-md',
          'transition-colors'
        ],
        leading: 'absolute inset-y-0 start-0 flex items-center',
        leadingIcon: 'shrink-0 text-dimmed',
        leadingAvatar: 'shrink-0',
        leadingAvatarSize: '',
        trailing: 'absolute inset-y-0 end-0 flex items-center',
        trailingIcon: 'shrink-0 text-dimmed',
        item: 'px-1.5 py-0.5 rounded-sm font-medium inline-flex items-center gap-0.5 ring ring-inset ring-accented bg-elevated text-default data-disabled:cursor-not-allowed data-disabled:opacity-75 wrap-anywhere data-[state="active"]:bg-accented',
        itemText: '',
        itemDelete: [
          'inline-flex items-center rounded-xs text-dimmed hover:text-default hover:bg-accented/75 disabled:pointer-events-none',
          'transition-colors'
        ],
        itemDeleteIcon: 'shrink-0',
        input: 'flex-1 border-0 bg-transparent placeholder:text-dimmed focus:outline-none disabled:cursor-not-allowed disabled:opacity-75'
      },
      variants: {
        fieldGroup: {
          horizontal: 'not-only:first:rounded-e-none not-only:last:rounded-s-none not-last:not-first:rounded-none focus-visible:z-[1]',
          vertical: 'not-only:first:rounded-b-none not-only:last:rounded-t-none not-last:not-first:rounded-none focus-visible:z-[1]'
        },
        size: {
          xs: {
            base: 'px-2 py-1 text-sm/4 gap-1',
            leading: 'ps-2',
            trailing: 'pe-2',
            leadingIcon: 'size-4',
            leadingAvatarSize: '3xs',
            trailingIcon: 'size-4',
            item: 'text-[10px]/3',
            itemDeleteIcon: 'size-3'
          },
          sm: {
            base: 'px-2.5 py-1.5 text-sm/4 gap-1.5',
            leading: 'ps-2.5',
            trailing: 'pe-2.5',
            leadingIcon: 'size-4',
            leadingAvatarSize: '3xs',
            trailingIcon: 'size-4',
            item: 'text-[10px]/3',
            itemDeleteIcon: 'size-3'
          },
          md: {
            base: 'px-2.5 py-1.5 text-base/5 gap-1.5',
            leading: 'ps-2.5',
            trailing: 'pe-2.5',
            leadingIcon: 'size-5',
            leadingAvatarSize: '2xs',
            trailingIcon: 'size-5',
            item: 'text-xs',
            itemDeleteIcon: 'size-3.5'
          },
          lg: {
            base: 'px-3 py-2 text-base/5 gap-2',
            leading: 'ps-3',
            trailing: 'pe-3',
            leadingIcon: 'size-5',
            leadingAvatarSize: '2xs',
            trailingIcon: 'size-5',
            item: 'text-xs',
            itemDeleteIcon: 'size-3.5'
          },
          xl: {
            base: 'px-3 py-2 text-base gap-2',
            leading: 'ps-3',
            trailing: 'pe-3',
            leadingIcon: 'size-6',
            leadingAvatarSize: 'xs',
            trailingIcon: 'size-6',
            item: 'text-sm',
            itemDeleteIcon: 'size-4'
          }
        },
        variant: {
          outline: 'text-highlighted bg-default ring ring-inset ring-accented',
          soft: 'text-highlighted bg-elevated/50 hover:bg-elevated has-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 has-focus:bg-elevated disabled:bg-transparent dark:disabled:bg-transparent',
          none: 'text-highlighted bg-transparent has-focus:outline-none'
        },
        color: {
          primary: '',
          secondary: '',
          success: '',
          info: '',
          warning: '',
          error: '',
          neutral: ''
        },
        leading: {
          true: ''
        },
        trailing: {
          true: ''
        },
        loading: {
          true: ''
        },
        highlight: {
          true: ''
        },
        fixed: {
          false: ''
        },
        type: {
          file: 'file:me-1.5 file:font-medium file:text-muted file:outline-none'
        }
      },
      compoundVariants: [
        {
          color: 'primary',
          variant: [
            'outline',
            'subtle'
          ],
          class: 'outline-primary/25 has-focus-visible:outline-3 has-focus-visible:ring-primary'
        },
        {
          color: 'primary',
          variant: [
            'soft',
            'ghost'
          ],
          class: 'outline-primary/25 has-focus-visible:outline-3'
        },
        {
          color: 'primary',
          highlight: true,
          class: 'ring ring-inset ring-primary'
        },
        {
          color: 'neutral',
          variant: [
            'outline',
            'subtle'
          ],
          class: 'outline-inverted/25 has-focus-visible:outline-3 has-focus-visible:ring-inverted'
        },
        {
          color: 'neutral',
          variant: [
            'soft',
            'ghost'
          ],
          class: 'outline-inverted/25 has-focus-visible:outline-3'
        },
        {
          color: 'neutral',
          highlight: true,
          class: 'ring ring-inset ring-inverted'
        },
        {
          leading: true,
          size: 'xs',
          class: 'ps-7'
        },
        {
          leading: true,
          size: 'sm',
          class: 'ps-8'
        },
        {
          leading: true,
          size: 'md',
          class: 'ps-9'
        },
        {
          leading: true,
          size: 'lg',
          class: 'ps-10'
        },
        {
          leading: true,
          size: 'xl',
          class: 'ps-11'
        },
        {
          trailing: true,
          size: 'xs',
          class: 'pe-7'
        },
        {
          trailing: true,
          size: 'sm',
          class: 'pe-8'
        },
        {
          trailing: true,
          size: 'md',
          class: 'pe-9'
        },
        {
          trailing: true,
          size: 'lg',
          class: 'pe-10'
        },
        {
          trailing: true,
          size: 'xl',
          class: 'pe-11'
        },
        {
          loading: true,
          leading: true,
          class: {
            leadingIcon: 'animate-spin'
          }
        },
        {
          loading: true,
          leading: false,
          trailing: true,
          class: {
            trailingIcon: 'animate-spin'
          }
        },
        {
          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: {
        inputTags: {
          slots: {
            root: [
              'relative inline-flex items-center',
              'flex-wrap'
            ],
            base: [
              'rounded-md',
              'transition-colors'
            ],
            leading: 'absolute inset-y-0 start-0 flex items-center',
            leadingIcon: 'shrink-0 text-dimmed',
            leadingAvatar: 'shrink-0',
            leadingAvatarSize: '',
            trailing: 'absolute inset-y-0 end-0 flex items-center',
            trailingIcon: 'shrink-0 text-dimmed',
            item: 'px-1.5 py-0.5 rounded-sm font-medium inline-flex items-center gap-0.5 ring ring-inset ring-accented bg-elevated text-default data-disabled:cursor-not-allowed data-disabled:opacity-75 wrap-anywhere data-[state="active"]:bg-accented',
            itemText: '',
            itemDelete: [
              'inline-flex items-center rounded-xs text-dimmed hover:text-default hover:bg-accented/75 disabled:pointer-events-none',
              'transition-colors'
            ],
            itemDeleteIcon: 'shrink-0',
            input: 'flex-1 border-0 bg-transparent placeholder:text-dimmed focus:outline-none disabled:cursor-not-allowed disabled:opacity-75'
          },
          variants: {
            fieldGroup: {
              horizontal: 'not-only:first:rounded-e-none not-only:last:rounded-s-none not-last:not-first:rounded-none focus-visible:z-[1]',
              vertical: 'not-only:first:rounded-b-none not-only:last:rounded-t-none not-last:not-first:rounded-none focus-visible:z-[1]'
            },
            size: {
              xs: {
                base: 'px-2 py-1 text-sm/4 gap-1',
                leading: 'ps-2',
                trailing: 'pe-2',
                leadingIcon: 'size-4',
                leadingAvatarSize: '3xs',
                trailingIcon: 'size-4',
                item: 'text-[10px]/3',
                itemDeleteIcon: 'size-3'
              },
              sm: {
                base: 'px-2.5 py-1.5 text-sm/4 gap-1.5',
                leading: 'ps-2.5',
                trailing: 'pe-2.5',
                leadingIcon: 'size-4',
                leadingAvatarSize: '3xs',
                trailingIcon: 'size-4',
                item: 'text-[10px]/3',
                itemDeleteIcon: 'size-3'
              },
              md: {
                base: 'px-2.5 py-1.5 text-base/5 gap-1.5',
                leading: 'ps-2.5',
                trailing: 'pe-2.5',
                leadingIcon: 'size-5',
                leadingAvatarSize: '2xs',
                trailingIcon: 'size-5',
                item: 'text-xs',
                itemDeleteIcon: 'size-3.5'
              },
              lg: {
                base: 'px-3 py-2 text-base/5 gap-2',
                leading: 'ps-3',
                trailing: 'pe-3',
                leadingIcon: 'size-5',
                leadingAvatarSize: '2xs',
                trailingIcon: 'size-5',
                item: 'text-xs',
                itemDeleteIcon: 'size-3.5'
              },
              xl: {
                base: 'px-3 py-2 text-base gap-2',
                leading: 'ps-3',
                trailing: 'pe-3',
                leadingIcon: 'size-6',
                leadingAvatarSize: 'xs',
                trailingIcon: 'size-6',
                item: 'text-sm',
                itemDeleteIcon: 'size-4'
              }
            },
            variant: {
              outline: 'text-highlighted bg-default ring ring-inset ring-accented',
              soft: 'text-highlighted bg-elevated/50 hover:bg-elevated has-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 has-focus:bg-elevated disabled:bg-transparent dark:disabled:bg-transparent',
              none: 'text-highlighted bg-transparent has-focus:outline-none'
            },
            color: {
              primary: '',
              secondary: '',
              success: '',
              info: '',
              warning: '',
              error: '',
              neutral: ''
            },
            leading: {
              true: ''
            },
            trailing: {
              true: ''
            },
            loading: {
              true: ''
            },
            highlight: {
              true: ''
            },
            fixed: {
              false: ''
            },
            type: {
              file: 'file:me-1.5 file:font-medium file:text-muted file:outline-none'
            }
          },
          compoundVariants: [
            {
              color: 'primary',
              variant: [
                'outline',
                'subtle'
              ],
              class: 'outline-primary/25 has-focus-visible:outline-3 has-focus-visible:ring-primary'
            },
            {
              color: 'primary',
              variant: [
                'soft',
                'ghost'
              ],
              class: 'outline-primary/25 has-focus-visible:outline-3'
            },
            {
              color: 'primary',
              highlight: true,
              class: 'ring ring-inset ring-primary'
            },
            {
              color: 'neutral',
              variant: [
                'outline',
                'subtle'
              ],
              class: 'outline-inverted/25 has-focus-visible:outline-3 has-focus-visible:ring-inverted'
            },
            {
              color: 'neutral',
              variant: [
                'soft',
                'ghost'
              ],
              class: 'outline-inverted/25 has-focus-visible:outline-3'
            },
            {
              color: 'neutral',
              highlight: true,
              class: 'ring ring-inset ring-inverted'
            },
            {
              leading: true,
              size: 'xs',
              class: 'ps-7'
            },
            {
              leading: true,
              size: 'sm',
              class: 'ps-8'
            },
            {
              leading: true,
              size: 'md',
              class: 'ps-9'
            },
            {
              leading: true,
              size: 'lg',
              class: 'ps-10'
            },
            {
              leading: true,
              size: 'xl',
              class: 'ps-11'
            },
            {
              trailing: true,
              size: 'xs',
              class: 'pe-7'
            },
            {
              trailing: true,
              size: 'sm',
              class: 'pe-8'
            },
            {
              trailing: true,
              size: 'md',
              class: 'pe-9'
            },
            {
              trailing: true,
              size: 'lg',
              class: 'pe-10'
            },
            {
              trailing: true,
              size: 'xl',
              class: 'pe-11'
            },
            {
              loading: true,
              leading: true,
              class: {
                leadingIcon: 'animate-spin'
              }
            },
            {
              loading: true,
              leading: false,
              trailing: true,
              class: {
                trailingIcon: 'animate-spin'
              }
            },
            {
              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'
          }
        }
      }
    })
  ]
})
Some colors in compoundVariants are omitted for readability. Check out the source code on GitHub.

Changelog

No recent changes