Empty

GitHub
显示空状态的组件。

用法

使用Empty组件可以在没有要显示的内容时显示占位符状态。

No projects found

It looks like you haven't added any projects. Create one to get started.

标题

使用title属性设置空状态的标题。

No projects found

<template>
  <UEmpty title="No projects found" />
</template>

说明

使用description属性设置空状态的描述。

No projects found

It looks like you haven't added any projects. Create one to get started.
<template>
  <UEmpty
    title="No projects found"
    description="It looks like you haven't added any projects. Create one to get started."
  />
</template>

Icon

使用icon prop设置空状态的图标。

No projects found

It looks like you haven't added any projects. Create one to get started.
<template>
  <UEmpty
    icon="i-lucide-file"
    title="No projects found"
    description="It looks like you haven't added any projects. Create one to get started."
  />
</template>

Avatar

使用avatar道具设置头像为空状态。

No projects found

It looks like you haven't added any projects. Create one to get started.
<template>
  <UEmpty
    :avatar="{
      src: 'https://github.com/nuxt.png'
    }"
    title="No projects found"
    description="It looks like you haven't added any projects. Create one to get started."
  />
</template>

加载中:badge{label="4.10+" class="align-text-top"}

使用loading道具显示一个加载图标来代替图标。布局保持不变,所以你可以在加载和清空状态之间切换而不会改变布局。

Loading projects

Please wait while we fetch your projects.
<template>
  <UEmpty
    icon="i-lucide-file"
    loading
    title="Loading projects"
    description="Please wait while we fetch your projects."
  />
</template>

加载图标:badge{label="4.10+" class="align-text-top"}

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

Loading projects

Please wait while we fetch your projects.
<template>
  <UEmpty
    icon="i-lucide-file"
    loading
    loading-icon="i-lucide-loader"
    title="Loading projects"
    description="Please wait while we fetch your projects."
  />
</template>
您可以在ui.icons.loading键下的app.config.ts中全局自定义此图标。
你可以在你的vite.config.ts中的ui.icons.loading键下全局自定义这个图标。

Actions

使用actions属性向空状态添加一些Button操作。

No projects found

It looks like you haven't added any projects. Create one to get started.
<template>
  <UEmpty
    icon="i-lucide-file"
    title="No projects found"
    description="It looks like you haven't added any projects. Create one to get started."
    :actions="[
      {
        icon: 'i-lucide-plus',
        label: 'Create new'
      },
      {
        icon: 'i-lucide-refresh-cw',
        label: 'Refresh',
        color: 'neutral',
        variant: 'subtle'
      }
    ]"
  />
</template>

Variant

使用variant prop更改空状态的变量。

No notifications

You're all caught up. New notifications will appear here.
<template>
  <UEmpty
    variant="naked"
    icon="i-lucide-bell"
    title="No notifications"
    description="You're all caught up. New notifications will appear here."
    :actions="[
      {
        icon: 'i-lucide-refresh-cw',
        label: 'Refresh',
        color: 'neutral',
        variant: 'subtle'
      }
    ]"
  />
</template>

Size

使用size属性来更改空状态的大小。

No notifications

You're all caught up. New notifications will appear here.
<template>
  <UEmpty
    size="xl"
    icon="i-lucide-bell"
    title="No notifications"
    description="You're all caught up. New notifications will appear here."
    :actions="[
      {
        icon: 'i-lucide-refresh-cw',
        label: 'Refresh',
        color: 'neutral',
        variant: 'subtle'
      }
    ]"
  />
</template>

示例

带插槽

使用可用插槽创建更复杂的空状态。

UnjsNuxt

No team members

Invite your team to collaborate on this project.
danielroe

Daniel Roe

danielroe

pi0

Pooya Parsa

pi0

atinux

Sébastien Chopin

atinux

benjamincanac

Benjamin Canac

benjamincanac

<script setup lang="ts">
import type { UserProps } from '@nuxt/ui'

const members: UserProps[] = [
  {
    name: 'Daniel Roe',
    description: 'danielroe',
    to: 'https://github.com/danielroe',
    target: '_blank',
    avatar: {
      src: 'https://github.com/danielroe.png',
      alt: 'danielroe',
      loading: 'lazy' as const
    }
  },
  {
    name: 'Pooya Parsa',
    description: 'pi0',
    to: 'https://github.com/pi0',
    target: '_blank',
    avatar: {
      src: 'https://github.com/pi0.png',
      alt: 'pi0',
      loading: 'lazy' as const
    }
  },
  {
    name: 'Sébastien Chopin',
    description: 'atinux',
    to: 'https://github.com/atinux',
    target: '_blank',
    avatar: {
      src: 'https://github.com/atinux.png',
      alt: 'atinux',
      loading: 'lazy' as const
    }
  },
  {
    name: 'Benjamin Canac',
    description: 'benjamincanac',
    to: 'https://github.com/benjamincanac',
    target: '_blank',
    avatar: {
      src: 'https://github.com/benjamincanac.png',
      alt: 'benjamincanac',
      loading: 'lazy' as const
    }
  }
]
</script>

<template>
  <UEmpty
    title="No team members"
    description="Invite your team to collaborate on this project."
    variant="naked"
    :actions="[{
      label: 'Invite members',
      icon: 'i-lucide-user-plus',
      color: 'neutral'
    }]"
  >
    <template #leading>
      <UAvatarGroup size="xl">
        <UAvatar src="https://github.com/nuxt.png" alt="Nuxt" loading="lazy" />
        <UAvatar src="https://github.com/unjs.png" alt="Unjs" loading="lazy" />
      </UAvatarGroup>
    </template>

    <template #footer>
      <USeparator class="my-4" />

      <div class="grid grid-cols-2 gap-4">
        <UPageCard
          v-for="(member, index) in members"
          :key="index"
          :to="member.to"
          :ui="{ container: 'sm:p-4' }"
        >
          <UUser
            :avatar="member.avatar"
            :name="member.name"
            :description="member.description"
            :ui="{ name: 'truncate' }"
          />
        </UPageCard>
      </div>
    </template>
  </UEmpty>
</template>

API

Props

Prop Default Type
as
'div'
any

The element or component this component should render as.

icon
any

The icon displayed above the title.

avatar
AvatarProps
loading
boolean

When true, the loading icon will be displayed.

loadingIcon
appConfig.ui.icons.loading
any

The icon when the loading prop is true.

title
string
description
string
actions
ButtonProps[]

Display a list of Button in the body.

variant
'outline'
"outline" | "solid" | "soft" | "subtle" | "naked"
size
'md'
"md" | "xs" | "sm" | "lg" | "xl"
ui
{ root?: SlotClass; header?: SlotClass; avatar?: SlotClass; title?: SlotClass; description?: SlotClass; body?: SlotClass; actions?: SlotClass; footer?: SlotClass; }

Slots

Slot Type
header
{}
leading
{ ui: object; }
title
{}
description
{}
body
{}
actions
{}
footer
{}

Theme

app.config.ts
export default defineAppConfig({
  ui: {
    empty: {
      slots: {
        root: 'relative flex flex-col items-center justify-center gap-4 rounded-lg p-4 sm:p-6 lg:p-8 min-w-0',
        header: 'flex flex-col items-center gap-2 max-w-sm text-center',
        avatar: 'shrink-0 mb-2',
        title: 'text-highlighted text-pretty font-medium',
        description: 'text-balance text-center',
        body: 'flex flex-col items-center gap-4 max-w-sm',
        actions: 'flex flex-wrap justify-center gap-2 shrink-0',
        footer: 'flex flex-col items-center gap-2 max-w-sm'
      },
      variants: {
        size: {
          xs: {
            avatar: 'size-8 text-base',
            title: 'text-sm',
            description: 'text-xs'
          },
          sm: {
            avatar: 'size-9 text-lg',
            title: 'text-sm',
            description: 'text-xs'
          },
          md: {
            avatar: 'size-10 text-xl',
            title: 'text-base',
            description: 'text-sm'
          },
          lg: {
            avatar: 'size-11 text-[22px]',
            title: 'text-base',
            description: 'text-sm'
          },
          xl: {
            avatar: 'size-12 text-2xl',
            title: 'text-lg',
            description: 'text-base'
          }
        },
        variant: {
          solid: {
            root: 'bg-inverted',
            title: 'text-inverted',
            description: 'text-dimmed'
          },
          outline: {
            root: 'bg-default ring ring-default',
            description: 'text-muted'
          },
          soft: {
            root: 'bg-elevated/50',
            description: 'text-toned'
          },
          subtle: {
            root: 'bg-elevated/50 ring ring-default',
            description: 'text-toned'
          },
          naked: {
            description: 'text-muted'
          }
        },
        loading: {
          true: {
            avatar: '[&>[data-slot=icon]]:animate-spin'
          }
        }
      },
      defaultVariants: {
        variant: 'outline',
        size: 'md'
      }
    }
  }
})
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: {
        empty: {
          slots: {
            root: 'relative flex flex-col items-center justify-center gap-4 rounded-lg p-4 sm:p-6 lg:p-8 min-w-0',
            header: 'flex flex-col items-center gap-2 max-w-sm text-center',
            avatar: 'shrink-0 mb-2',
            title: 'text-highlighted text-pretty font-medium',
            description: 'text-balance text-center',
            body: 'flex flex-col items-center gap-4 max-w-sm',
            actions: 'flex flex-wrap justify-center gap-2 shrink-0',
            footer: 'flex flex-col items-center gap-2 max-w-sm'
          },
          variants: {
            size: {
              xs: {
                avatar: 'size-8 text-base',
                title: 'text-sm',
                description: 'text-xs'
              },
              sm: {
                avatar: 'size-9 text-lg',
                title: 'text-sm',
                description: 'text-xs'
              },
              md: {
                avatar: 'size-10 text-xl',
                title: 'text-base',
                description: 'text-sm'
              },
              lg: {
                avatar: 'size-11 text-[22px]',
                title: 'text-base',
                description: 'text-sm'
              },
              xl: {
                avatar: 'size-12 text-2xl',
                title: 'text-lg',
                description: 'text-base'
              }
            },
            variant: {
              solid: {
                root: 'bg-inverted',
                title: 'text-inverted',
                description: 'text-dimmed'
              },
              outline: {
                root: 'bg-default ring ring-default',
                description: 'text-muted'
              },
              soft: {
                root: 'bg-elevated/50',
                description: 'text-toned'
              },
              subtle: {
                root: 'bg-elevated/50 ring ring-default',
                description: 'text-toned'
              },
              naked: {
                description: 'text-muted'
              }
            },
            loading: {
              true: {
                avatar: '[&>[data-slot=icon]]:animate-spin'
              }
            }
          },
          defaultVariants: {
            variant: 'outline',
            size: 'md'
          }
        }
      }
    })
  ]
})

Changelog

No recent changes