博客文章

GitHub
一个可自定义的文章,用于在博客页面中显示。

用法

BlogPost 组件提供了一种灵活的方式来显示 <article> 元素,其内容可自定义,包括标题、描述、图片等。

Introducing Nuxt Icon v1

Nuxt Icon v1 介绍

探索 Nuxt Icon v1——一个现代、通用、可定制的 Nuxt 项目图标解决方案。
Anthony Fu

Anthony Fu

antfu7

使用 BlogPosts 组件以响应式网格布局显示多篇博客文章。

标题

使用 title 属性显示 BlogPost 的标题。

Nuxt Icon v1 介绍

<template>
  <UBlogPost title="Introducing Nuxt Icon v1" />
</template>

描述

使用 description 属性显示 BlogPost 的描述。

Nuxt Icon v1 介绍

探索 Nuxt Icon v1——一个现代、通用、可定制的 Nuxt 项目图标解决方案。
<template>
  <UBlogPost
    title="Introducing Nuxt Icon v1"
    description="Discover Nuxt Icon v1 - a modern, versatile, and customizable icon solution for your Nuxt projects."
  />
</template>

日期

使用 date 属性显示 BlogPost 的日期。

日期会自动格式化为当前区域设置。您可以传入 Date 对象或字符串。

Nuxt Icon v1 介绍

探索 Nuxt Icon v1——一个现代、通用、可定制的 Nuxt 项目图标解决方案。
<template>
  <UBlogPost
    title="Introducing Nuxt Icon v1"
    description="Discover Nuxt Icon v1 - a modern, versatile, and customizable icon solution for your Nuxt projects."
    date="2024-11-25"
  />
</template>

Badge

使用 badge 属性在 BlogPost 中显示 Badge

发布

Nuxt Icon v1 介绍

探索 Nuxt Icon v1——一个现代、通用、可定制的 Nuxt 项目图标解决方案。
<template>
  <UBlogPost
    title="Introducing Nuxt Icon v1"
    description="Discover Nuxt Icon v1 - a modern, versatile, and customizable icon solution for your Nuxt projects."
    badge="Release"
  />
</template>

您可以传递 Badge 组件的任何属性来对其进行自定义。

发布

Nuxt Icon v1 介绍

探索 Nuxt Icon v1——一个现代、通用、可定制的 Nuxt 项目图标解决方案。
<template>
  <UBlogPost
    title="Introducing Nuxt Icon v1"
    description="Discover Nuxt Icon v1 - a modern, versatile, and customizable icon solution for your Nuxt projects."
    :badge="{
      label: 'Release',
      color: 'primary',
      variant: 'solid'
    }"
  />
</template>

图片

使用 image 属性在 BlogPost 中显示图像。

如果@nuxt/image安装后,将使用 <NuxtImg> 组件而不是原生的 img 标签。
Introducing Nuxt Icon v1

Nuxt Icon v1 介绍

探索 Nuxt Icon v1——一个现代、通用、可定制的 Nuxt 项目图标解决方案。
<template>
  <UBlogPost
    title="Introducing Nuxt Icon v1"
    description="Discover Nuxt Icon v1 - a modern, versatile, and customizable icon solution for your Nuxt projects."
    image="https://nuxtjs.org.cn/assets/blog/nuxt-icon/cover.png"
    date="2024-11-25"
  />
</template>

作者

使用 authors 属性显示 BlogPost 中用户列表作为具有以下属性的对象数组

  • name?: string
  • description?: string
  • avatar?: Omit<AvatarProps, 'size'>
  • chip?: boolean | Omit<ChipProps, 'size' | 'inset'>
  • size?: UserProps['size']
  • orientation?: UserProps['orientation']

您可以传递 Link 组件的任何属性,例如 totarget 等。

Introducing Nuxt Icon v1

Nuxt Icon v1 介绍

探索 Nuxt Icon v1——一个现代、通用、可定制的 Nuxt 项目图标解决方案。
Anthony Fu

Anthony Fu

antfu7

<script setup lang="ts">
const authors = ref([
  {
    name: 'Anthony Fu',
    description: 'antfu7',
    avatar: {
      src: 'https://github.com/antfu.png'
    },
    to: 'https://github.com/antfu',
    target: '_blank'
  }
])
</script>

<template>
  <UBlogPost
    title="Introducing Nuxt Icon v1"
    description="Discover Nuxt Icon v1 - a modern, versatile, and customizable icon solution for your Nuxt projects."
    image="https://nuxtjs.org.cn/assets/blog/nuxt-icon/cover.png"
    date="2024-11-25"
    :authors="authors"
  />
</template>

authors 属性包含多项时,将使用 AvatarGroup 组件。

Introducing Nuxt Icon v1

Nuxt Icon v1 介绍

探索 Nuxt Icon v1——一个现代、通用、可定制的 Nuxt 项目图标解决方案。
<script setup lang="ts">
const authors = ref([
  {
    name: 'Anthony Fu',
    description: 'antfu7',
    avatar: {
      src: 'https://github.com/antfu.png'
    },
    to: 'https://github.com/antfu',
    target: '_blank'
  },
  {
    name: 'Benjamin Canac',
    description: 'benjamincanac',
    avatar: {
      src: 'https://github.com/benjamincanac.png'
    },
    to: 'https://github.com/benjamincanac',
    target: '_blank'
  }
])
</script>

<template>
  <UBlogPost
    title="Introducing Nuxt Icon v1"
    description="Discover Nuxt Icon v1 - a modern, versatile, and customizable icon solution for your Nuxt projects."
    image="https://nuxtjs.org.cn/assets/blog/nuxt-icon/cover.png"
    date="2024-11-25"
    :authors="authors"
  />
</template>

您可以传递<NuxtLink>组件,例如 totargetrel 等。

Introducing Nuxt Icon v1

Nuxt Icon v1 介绍

探索 Nuxt Icon v1——一个现代、通用、可定制的 Nuxt 项目图标解决方案。
<template>
  <UBlogPost
    title="Introducing Nuxt Icon v1"
    description="Discover Nuxt Icon v1 - a modern, versatile, and customizable icon solution for your Nuxt projects."
    image="https://nuxtjs.org.cn/assets/blog/nuxt-icon/cover.png"
    date="2024-11-25"
    to="https://nuxtjs.org.cn/blog/nuxt-icon-v1-0"
    target="_blank"
  />
</template>

变体

使用 variant 属性更改 BlogPost 的样式。

Introducing Nuxt Icon v1

Nuxt Icon v1 介绍

探索 Nuxt Icon v1——一个现代、通用、可定制的 Nuxt 项目图标解决方案。
<template>
  <UBlogPost
    title="Introducing Nuxt Icon v1"
    description="Discover Nuxt Icon v1 - a modern, versatile, and customizable icon solution for your Nuxt projects."
    image="https://nuxtjs.org.cn/assets/blog/nuxt-icon/cover.png"
    date="2024-11-25"
    to="https://nuxtjs.org.cn/blog/nuxt-icon-v1-0"
    target="_blank"
    variant="naked"
  />
</template>
样式将根据您是否提供 to 属性或 image 属性而有所不同。

Orientation

使用 orientation 属性更改 BlogPost 的方向。默认为 vertical

Introducing Nuxt Icon v1

Nuxt Icon v1 介绍

探索 Nuxt Icon v1——一个现代、通用、可定制的 Nuxt 项目图标解决方案。
<template>
  <UBlogPost
    title="Introducing Nuxt Icon v1"
    description="Discover Nuxt Icon v1 - a modern, versatile, and customizable icon solution for your Nuxt projects."
    image="https://nuxtjs.org.cn/assets/blog/nuxt-icon/cover.png"
    date="2024-11-25"
    to="https://nuxtjs.org.cn/blog/nuxt-icon-v1-0"
    target="_blank"
    orientation="horizontal"
    variant="outline"
  />
</template>

API

属性

属性默认值类型
as

'article'

any

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

title

string

description

string

日期

string | Date

博客文章的日期。可以是字符串或 Date 对象。

徽章

string | BadgeProps

在博客文章上显示一个徽章。可以是字符串或对象。{ color: 'neutral', variant: 'subtle' }

authors

UserProps[]

博客文章的作者。

图片

string | Partial<HTMLImageElement> & { [key: string]: any; }

博客文章的图片。可以是字符串或对象。

orientation

'vertical'

"vertical" | "horizontal"

博客文章的方向。

variant

'outline'

"outline" | "soft" | "subtle" | "ghost" | "naked"

过渡到

字符串 | RouteLocationAsRelativeGeneric | RouteLocationAsPathGeneric

target

null | "_blank" | "_parent" | "_self" | "_top" | string & {}

ui

{ root?: ClassNameValue; header?: ClassNameValue; body?: ClassNameValue; footer?: ClassNameValue; image?: ClassNameValue; title?: ClassNameValue; description?: ClassNameValue; authors?: ClassNameValue; avatar?: ClassNameValue; meta?: ClassNameValue; date?: ClassNameValue; badge?: ClassNameValue; }

插槽

插槽类型
日期

{}

徽章

{}

title

{}

description

{}

authors

{ ui: object; }

页头

{ ui: object; }

主体

{}

页脚

{}

主题

app.config.ts
export default defineAppConfig({
  ui: {
    blogPost: {
      slots: {
        root: 'relative group/blog-post flex flex-col rounded-lg overflow-hidden',
        header: 'relative overflow-hidden aspect-[16/9] w-full pointer-events-none',
        body: 'min-w-0 flex-1 flex flex-col',
        footer: '',
        image: 'object-cover object-top w-full h-full',
        title: 'text-xl text-pretty font-semibold text-highlighted',
        description: 'mt-1 text-base text-pretty',
        authors: 'pt-4 mt-auto flex flex-wrap gap-x-3 gap-y-1.5',
        avatar: '',
        meta: 'flex items-center gap-2 mb-2',
        date: 'text-sm',
        badge: ''
      },
      variants: {
        orientation: {
          horizontal: {
            root: 'lg:grid lg:grid-cols-2 lg:items-center gap-x-8',
            body: 'justify-center p-4 sm:p-6 lg:px-0'
          },
          vertical: {
            root: 'flex flex-col',
            body: 'p-4 sm:p-6'
          }
        },
        variant: {
          outline: {
            root: 'bg-default ring ring-default',
            date: 'text-toned',
            description: 'text-muted'
          },
          soft: {
            root: 'bg-elevated/50',
            date: 'text-muted',
            description: 'text-toned'
          },
          subtle: {
            root: 'bg-elevated/50 ring ring-default',
            date: 'text-muted',
            description: 'text-toned'
          },
          ghost: {
            date: 'text-toned',
            description: 'text-muted',
            header: 'shadow-lg rounded-lg'
          },
          naked: {
            root: 'p-0 sm:p-0',
            date: 'text-toned',
            description: 'text-muted',
            header: 'shadow-lg rounded-lg'
          }
        },
        to: {
          true: {
            root: [
              'transition'
            ],
            image: 'transform transition-transform duration-200 group-hover/blog-post:scale-110',
            avatar: 'transform transition-transform duration-200 hover:scale-115'
          }
        },
        image: {
          true: ''
        }
      },
      compoundVariants: [
        {
          variant: 'outline',
          to: true,
          class: {
            root: 'hover:bg-elevated/50'
          }
        },
        {
          variant: 'soft',
          to: true,
          class: {
            root: 'hover:bg-elevated'
          }
        },
        {
          variant: 'subtle',
          to: true,
          class: {
            root: 'hover:bg-elevated hover:ring-accented'
          }
        },
        {
          variant: 'ghost',
          to: true,
          class: {
            root: 'hover:bg-elevated/50',
            header: [
              'group-hover/blog-post:shadow-none',
              'transition-all'
            ]
          }
        },
        {
          variant: 'ghost',
          to: true,
          orientation: 'vertical',
          class: {
            header: 'group-hover/blog-post:rounded-b-none'
          }
        },
        {
          variant: 'ghost',
          to: true,
          orientation: 'horizontal',
          class: {
            header: 'group-hover/blog-post:rounded-r-none'
          }
        },
        {
          orientation: 'vertical',
          image: false,
          variant: 'naked',
          class: {
            body: 'p-0 sm:p-0'
          }
        }
      ],
      defaultVariants: {
        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: {
        blogPost: {
          slots: {
            root: 'relative group/blog-post flex flex-col rounded-lg overflow-hidden',
            header: 'relative overflow-hidden aspect-[16/9] w-full pointer-events-none',
            body: 'min-w-0 flex-1 flex flex-col',
            footer: '',
            image: 'object-cover object-top w-full h-full',
            title: 'text-xl text-pretty font-semibold text-highlighted',
            description: 'mt-1 text-base text-pretty',
            authors: 'pt-4 mt-auto flex flex-wrap gap-x-3 gap-y-1.5',
            avatar: '',
            meta: 'flex items-center gap-2 mb-2',
            date: 'text-sm',
            badge: ''
          },
          variants: {
            orientation: {
              horizontal: {
                root: 'lg:grid lg:grid-cols-2 lg:items-center gap-x-8',
                body: 'justify-center p-4 sm:p-6 lg:px-0'
              },
              vertical: {
                root: 'flex flex-col',
                body: 'p-4 sm:p-6'
              }
            },
            variant: {
              outline: {
                root: 'bg-default ring ring-default',
                date: 'text-toned',
                description: 'text-muted'
              },
              soft: {
                root: 'bg-elevated/50',
                date: 'text-muted',
                description: 'text-toned'
              },
              subtle: {
                root: 'bg-elevated/50 ring ring-default',
                date: 'text-muted',
                description: 'text-toned'
              },
              ghost: {
                date: 'text-toned',
                description: 'text-muted',
                header: 'shadow-lg rounded-lg'
              },
              naked: {
                root: 'p-0 sm:p-0',
                date: 'text-toned',
                description: 'text-muted',
                header: 'shadow-lg rounded-lg'
              }
            },
            to: {
              true: {
                root: [
                  'transition'
                ],
                image: 'transform transition-transform duration-200 group-hover/blog-post:scale-110',
                avatar: 'transform transition-transform duration-200 hover:scale-115'
              }
            },
            image: {
              true: ''
            }
          },
          compoundVariants: [
            {
              variant: 'outline',
              to: true,
              class: {
                root: 'hover:bg-elevated/50'
              }
            },
            {
              variant: 'soft',
              to: true,
              class: {
                root: 'hover:bg-elevated'
              }
            },
            {
              variant: 'subtle',
              to: true,
              class: {
                root: 'hover:bg-elevated hover:ring-accented'
              }
            },
            {
              variant: 'ghost',
              to: true,
              class: {
                root: 'hover:bg-elevated/50',
                header: [
                  'group-hover/blog-post:shadow-none',
                  'transition-all'
                ]
              }
            },
            {
              variant: 'ghost',
              to: true,
              orientation: 'vertical',
              class: {
                header: 'group-hover/blog-post:rounded-b-none'
              }
            },
            {
              variant: 'ghost',
              to: true,
              orientation: 'horizontal',
              class: {
                header: 'group-hover/blog-post:rounded-r-none'
              }
            },
            {
              orientation: 'vertical',
              image: false,
              variant: 'naked',
              class: {
                body: 'p-0 sm:p-0'
              }
            }
          ],
          defaultVariants: {
            variant: 'outline'
          }
        }
      }
    })
  ]
})

更新日志

9632f— 修复:允许在 image 属性中包含任何属性

63c0a— feat: 在使用的 slot prop 中暴露 ui (#5207)

45148— 修复:确保日期插槽渲染 (#4743)

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