Lzh on GitHub

Avatar

一个带回退功能和 Nuxt Image 支持的 img 元素。

用法

Avatar.vue 是 Nuxt UI 中的一个多功能头像组件,它旨在提供一个统一、美观且具有回退机制的头像显示方案。它智能地利用 @nuxt/image 进行图片优化,并在图片加载失败或未提供图片时,能优雅地回退到图标或文本显示。

当安装了 @nuxt/image 时,Avatar 使用 <NuxtImg> 组件,否则回退到 img

你可以传递 HTML <img> 元素的任何属性,例如 altloading 等。

Src

使用 src prop 来设置图片 URL。

<template>
  <UAvatar src="https://github.com/benjamincanac.png" />
</template>

尺寸(Size)

使用 size prop 来设置 Avatar 的尺寸。

<template>
  <UAvatar src="https://github.com/benjamincanac.png" size="xl" />
</template>
<img> 元素的 widthheight 会根据 size prop 自动设置。

图标(Icon)

使用 icon prop 来显示一个回退 Icon

<template>
  <UAvatar icon="i-lucide-image" size="md" />
</template>

文本(Text)

使用 text prop 来显示一个回退文本。

+1
<template>
  <UAvatar text="+1" size="md" />
</template>

Alt

当没有提供图标或文本时,alt prop 的 首字母缩 写将用作回退。

BC
<template>
  <UAvatar alt="Benjamin Canac" size="md" />
</template>
alt prop 会作为 alt 属性传递给 img 元素。

示例

使用 tooltip

你可以使用 Tooltip 组件在鼠标悬停 Avatar 时显示工具提示。

<template>
  <UTooltip text="Benjamin Canac">
    <UAvatar
      src="https://github.com/benjamincanac.png"
      alt="Benjamin Canac"
    />
  </UTooltip>
</template>

使用徽章

你可以使用 Chip 组件在 Avatar 周围显示一个徽章。

<template>
  <UChip inset>
    <UAvatar
      src="https://github.com/benjamincanac.png"
      alt="Benjamin Canac"
    />
  </UChip>
</template>

可以使用 chip prop 实现徽章。

chip prop 值类型:

  • boolean:如果为 true,头像会被包裹在一个默认的 UChip 组件中。
  • ChipProps:可以传入一个对象,来完全配置 UChip 组件的属性(如 color, position, text 等)。
<UAvatar src="..." chip /> 
<UAvatar src="..." :chip="{ text: 'New', color: 'red', position: 'top-right' }" />

API

Props

Prop Default Type
as

'span'

any

The element or component this component should render as.

src

string

alt

string

icon

string

text

string

size

'md'

"2xl" | "md" | "3xs" | "2xs" | "xs" | "sm" | "lg" | "xl" | "3xl"

chip

boolean | ChipProps

ui

{ root?: ClassNameValue; image?: ClassNameValue; fallback?: ClassNameValue; icon?: ClassNameValue; }

Theme

app.config.ts
export default defineAppConfig({
  ui: {
    avatar: {
      slots: {
        root: 'inline-flex items-center justify-center shrink-0 select-none rounded-full align-middle bg-elevated',
        image: 'h-full w-full rounded-[inherit] object-cover',
        fallback: 'font-medium leading-none text-muted truncate',
        icon: 'text-muted shrink-0'
      },
      variants: {
        size: {
          '3xs': {
            root: 'size-4 text-[8px]'
          },
          '2xs': {
            root: 'size-5 text-[10px]'
          },
          xs: {
            root: 'size-6 text-xs'
          },
          sm: {
            root: 'size-7 text-sm'
          },
          md: {
            root: 'size-8 text-base'
          },
          lg: {
            root: 'size-9 text-lg'
          },
          xl: {
            root: 'size-10 text-xl'
          },
          '2xl': {
            root: 'size-11 text-[22px]'
          },
          '3xl': {
            root: 'size-12 text-2xl'
          }
        }
      },
      defaultVariants: {
        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: {
        avatar: {
          slots: {
            root: 'inline-flex items-center justify-center shrink-0 select-none rounded-full align-middle bg-elevated',
            image: 'h-full w-full rounded-[inherit] object-cover',
            fallback: 'font-medium leading-none text-muted truncate',
            icon: 'text-muted shrink-0'
          },
          variants: {
            size: {
              '3xs': {
                root: 'size-4 text-[8px]'
              },
              '2xs': {
                root: 'size-5 text-[10px]'
              },
              xs: {
                root: 'size-6 text-xs'
              },
              sm: {
                root: 'size-7 text-sm'
              },
              md: {
                root: 'size-8 text-base'
              },
              lg: {
                root: 'size-9 text-lg'
              },
              xl: {
                root: 'size-10 text-xl'
              },
              '2xl': {
                root: 'size-11 text-[22px]'
              },
              '3xl': {
                root: 'size-12 text-2xl'
              }
            }
          },
          defaultVariants: {
            size: 'md'
          }
        }
      }
    })
  ]
})
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: {
        avatar: {
          slots: {
            root: 'inline-flex items-center justify-center shrink-0 select-none rounded-full align-middle bg-elevated',
            image: 'h-full w-full rounded-[inherit] object-cover',
            fallback: 'font-medium leading-none text-muted truncate',
            icon: 'text-muted shrink-0'
          },
          variants: {
            size: {
              '3xs': {
                root: 'size-4 text-[8px]'
              },
              '2xs': {
                root: 'size-5 text-[10px]'
              },
              xs: {
                root: 'size-6 text-xs'
              },
              sm: {
                root: 'size-7 text-sm'
              },
              md: {
                root: 'size-8 text-base'
              },
              lg: {
                root: 'size-9 text-lg'
              },
              xl: {
                root: 'size-10 text-xl'
              },
              '2xl': {
                root: 'size-11 text-[22px]'
              },
              '3xl': {
                root: 'size-12 text-2xl'
              }
            }
          },
          defaultVariants: {
            size: 'md'
          }
        }
      }
    })
  ]
})