PinnovateCloud-realease/components/news/TrendingNewsList.vue
2025-05-23 16:00:15 +08:00

130 lines
3.8 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!-- 热门新闻列表组件 -->
<template>
<div class="trending-news">
<div class="trending-news-header">
<h3 class="font-semibold text-lg mb-3 dark:text-white">
<i class="fas fa-fire text-red-500 dark:text-red-400 mr-2"></i>
{{ $t('news.trendingNews') }}
</h3>
</div>
<div class="trending-news-list">
<NuxtLink
v-for="(article, index) in trendingNews"
:key="index"
:to="`/awsnews/${getArticleSlug(article)}`"
class="trending-news-item"
>
<div class="trending-news-rank">{{ index + 1 }}</div>
<div class="trending-news-content">
<h4 class="trending-news-title">{{ article.title }}</h4>
<div class="trending-news-meta">
<span class="trending-news-category" :class="getCategoryClass(article.category || article.meta?.category || 'other')">
{{ $t(`news.categories.${article.category || article.meta?.category || 'other'}`) }}
</span>
<!-- <span class="trending-news-views">
<i class="fas fa-eye text-gray-400 mr-1"></i> {{ article.views }}
</span> -->
</div>
</div>
</NuxtLink>
</div>
</div>
</template>
<script setup lang="ts">
import type { PropType } from 'vue';
import { useI18n } from 'vue-i18n';
const { t } = useI18n();
// 定义组件属性
const props = defineProps({
trendingNews: {
type: Array as PropType<any[]>,
required: true
}
});
// 安全获取文章路径最后部分slug
const getArticleSlug = (article: any) => {
if (!article) return '';
// 优先使用path如果没有则尝试使用_path
const path = article.path || article._path || '';
// 移除开头的斜杠
const cleanPath = path.startsWith('/') ? path.substring(1) : path;
// 如果路径中包含斜杠,取最后一段;否则使用整个路径
return cleanPath.includes('/') ? cleanPath.split('/').pop() : cleanPath;
};
// 获取分类样式
const getCategoryClass = (category: string) => {
const categoryColors: Record<string, string> = {
'cloud-computing': 'text-blue-600',
'security': 'text-red-600',
'serverless': 'text-purple-600',
'ai': 'text-green-600',
'database': 'text-yellow-600',
'quantum-computing': 'text-blue-700',
'networking': 'text-blue-500',
'containers': 'text-blue-600',
'machine-learning': 'text-blue-500',
'sustainability': 'text-blue-600',
'other': 'text-gray-600'
};
return categoryColors[category] || categoryColors.other;
};
</script>
<style scoped>
.trending-news {
@apply bg-white dark:bg-gray-800 rounded-lg shadow p-4 mt-6 sticky top-24;
}
.trending-news-list {
@apply space-y-4;
}
.trending-news-item {
@apply flex items-start py-2 border-b border-gray-100 dark:border-gray-700 last:border-0 hover:bg-gray-50 dark:hover:bg-gray-700/50 transition-colors;
}
.trending-news-rank {
@apply flex-shrink-0 w-6 h-6 rounded-full bg-gray-100 dark:bg-gray-700 flex items-center justify-center text-sm font-bold text-gray-700 dark:text-gray-300 mr-3;
}
.trending-news-item:nth-child(1) .trending-news-rank {
@apply bg-red-100 dark:bg-red-900/30 text-red-700 dark:text-red-400;
}
.trending-news-item:nth-child(2) .trending-news-rank {
@apply bg-orange-100 dark:bg-orange-900/30 text-orange-700 dark:text-orange-400;
}
.trending-news-item:nth-child(3) .trending-news-rank {
@apply bg-yellow-100 dark:bg-yellow-900/30 text-yellow-700 dark:text-yellow-400;
}
.trending-news-content {
@apply flex-grow;
}
.trending-news-title {
@apply text-sm font-medium mb-1 line-clamp-2 dark:text-white;
}
.trending-news-meta {
@apply flex justify-between items-center text-xs;
}
.trending-news-category {
@apply font-medium;
}
.trending-news-views {
@apply text-gray-500 dark:text-gray-400;
}
</style>