博客文章

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 中显示 User(用户) 列表,这些对象包含以下属性

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

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

Introducing Nuxt Icon v1

Nuxt Icon v1 介绍

探索 Nuxt Icon v1——为您的 Nuxt 项目提供的一款现代、通用且可自定义的图标解决方案。
Anthony Fu

Anthony Fu

antfu7

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

const authors = ref<UserProps[]>([
  {
    name: 'Anthony Fu',
    description: 'antfu7',
    avatar: {
      src: 'https://github.com/antfu.png',
      loading: 'lazy'
    },
    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>
<script setup lang="ts">
import { ref } from 'vue'
import type { UserProps } from '@nuxt/ui'

const authors = ref<UserProps[]>([
  {
    name: 'Anthony Fu',
    description: 'antfu7',
    avatar: {
      src: 'https://github.com/antfu.png',
      loading: 'lazy'
    },
    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">
import type { UserProps } from '@nuxt/ui'

const authors = ref<UserProps[]>([
  {
    name: 'Anthony Fu',
    description: 'antfu7',
    avatar: {
      src: 'https://github.com/antfu.png',
      loading: 'lazy'
    },
    to: 'https://github.com/antfu',
    target: '_blank'
  },
  {
    name: 'Benjamin Canac',
    description: 'benjamincanac',
    avatar: {
      src: 'https://github.com/benjamincanac.png',
      loading: 'lazy'
    },
    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>
<script setup lang="ts">
import { ref } from 'vue'
import type { UserProps } from '@nuxt/ui'

const authors = ref<UserProps[]>([
  {
    name: 'Anthony Fu',
    description: 'antfu7',
    avatar: {
      src: 'https://github.com/antfu.png',
      loading: 'lazy'
    },
    to: 'https://github.com/antfu',
    target: '_blank'
  },
  {
    name: 'Benjamin Canac',
    description: 'benjamincanac',
    avatar: {
      src: 'https://github.com/benjamincanac.png',
      loading: 'lazy'
    },
    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> 组件的任何属性,例如 to, target, rel 等。

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

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

titlestring
descriptionstring
日期string | Date

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

徽章字符串 | BadgeProps

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

authorsUserProps[]

博文的作者。

图片string | Partial<ImgHTMLAttributes> & { [key: string]: any; }

博文的图像。可以是字符串或对象。

orientation'vertical'"vertical" | "horizontal"

博文的方向。

variant'outline'"outline" | "soft" | "subtle" | "ghost" | "naked"
过渡到string | it | et
targetnull | "_blank" | "_parent" | "_self" | "_top" | string & {}
ui{ root?: SlotClass; header?: SlotClass; body?: SlotClass; footer?: SlotClass; image?: SlotClass; title?: SlotClass; description?: SlotClass; authors?: SlotClass; avatar?: SlotClass; meta?: SlotClass; date?: SlotClass; badge?: SlotClass; }

插槽

插槽类型
日期{}
徽章{}
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: [
              'outline-primary/25 has-[>a:focus-visible]:outline-3',
              'transition'
            ],
            image: 'transform transition-transform duration-200 group-hover/blog-post:scale-110',
            avatar: 'inline-flex transform transition-transform duration-200 hover:scale-115 rounded-full outline-primary/25 focus-visible:outline-3'
          }
        },
        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: [
            'outline',
            'subtle'
          ],
          to: true,
          class: {
            root: 'has-[>a:focus-visible]:ring-primary'
          }
        },
        {
          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: [
                  'outline-primary/25 has-[>a:focus-visible]:outline-3',
                  'transition'
                ],
                image: 'transform transition-transform duration-200 group-hover/blog-post:scale-110',
                avatar: 'inline-flex transform transition-transform duration-200 hover:scale-115 rounded-full outline-primary/25 focus-visible:outline-3'
              }
            },
            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: [
                'outline',
                'subtle'
              ],
              to: true,
              class: {
                root: 'has-[>a:focus-visible]:ring-primary'
              }
            },
            {
              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'
          }
        }
      }
    })
  ]
})

更新日志

暂无近期更新