2025-09-05 14:59:21 +08:00

82 lines
2.3 KiB
Vue

<template>
<div class="max-w-7xl mx-auto px-4 py-12">
<div class="text-center mb-12">
<h1 class="text-4xl font-bold text-gray-900 mb-4">{{ $t('nav.blog') }}</h1>
<p class="text-xl text-gray-600">{{ $t('seo.blog.description') }}</p>
</div>
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8">
<article
v-for="article in articles"
:key="article._path"
class="bg-white rounded-lg shadow-md overflow-hidden hover:shadow-lg transition-shadow"
>
<img
v-if="article.image"
:src="article.image"
:alt="article.title"
class="w-full h-48 object-cover"
/>
<div class="p-6">
<h2 class="text-xl font-semibold mb-2">
<NuxtLink
:to="getArticlePath(article)"
class="text-gray-900 hover:text-blue-600"
>
{{ article.title }}
</NuxtLink>
</h2>
<p class="text-gray-600 mb-4">{{ article.description }}</p>
<div class="flex items-center justify-between">
<time class="text-sm text-gray-500">{{ formatDate(article.date) }}</time>
<NuxtLink
:to="getArticlePath(article)"
class="text-blue-600 hover:text-blue-800 font-medium"
>
Read More
</NuxtLink>
</div>
</div>
</article>
</div>
</div>
</template>
<script setup>
const { locale, t } = useI18n()
const localePath = useLocalePath()
// 获取当前语言的文章
const { data: articles } = await useAsyncData('blog', () =>
queryContent(`/${locale.value}`)
.where({ _partial: false })
.sort({ date: -1 })
.find()
)
const formatDate = (date) => {
return new Date(date).toLocaleDateString(locale.value, {
year: 'numeric',
month: 'long',
day: 'numeric'
})
}
const getArticlePath = (article) => {
// 使用文章的slug字段
const slug = article.slug || article._path.split('/').pop().replace('.md', '')
// 英文是默认语言,不需要添加语言路径
if (locale.value === 'en') {
return `/blog/${slug}`
}
return `/${locale.value}/blog/${slug}`
}
// SEO设置
useSeoMeta({
title: () => t('seo.blog.title'),
description: () => t('seo.blog.description')
})
</script>