228 lines
7.0 KiB
Vue
Raw Permalink Normal View History

2025-05-23 16:00:15 +08:00
<template>
<div class="py-16 bg-gray-50 dark:bg-gray-900 min-h-screen">
<div class="container">
<!-- <h1 class="text-3xl font-bold mb-8 text-center text-primary">{{ $t('产品标签') }}</h1> -->
<div class="flex flex-wrap gap-4 justify-center">
<NuxtLink
v-for="nav in navlist"
:key="nav.path"
:to="`/${lang}${nav.path}`"
class="px-4 py-2 bg-white dark:bg-gray-800 rounded-full shadow hover:bg-primary hover:text-white dark:hover:bg-primary transition-colors text-primary dark:text-primary-light border border-primary dark:border-primary-light"
>
{{ t("nav." + nav.key) }}
</NuxtLink>
<NuxtLink
v-for="tag in tags"
:key="tag"
:to="`/${lang}/tag/${tag}`"
class="px-4 py-2 bg-white dark:bg-gray-800 rounded-full shadow hover:bg-primary hover:text-white dark:hover:bg-primary transition-colors text-primary dark:text-primary-light border border-primary dark:border-primary-light"
>
{{ t("tags." + tag) }}
</NuxtLink>
</div>
</div>
<div class="mt-12 container">
<h2 class="text-2xl font-bold mb-8 text-center text-primary dark:text-primary-light">{{ t('aws.featuredContent') }}</h2>
<!-- 轮播图组件 -->
<div class="carousel-container relative overflow-hidden rounded-lg shadow-lg max-w-5xl mx-auto">
<!-- 轮播图内容 -->
<div class="carousel-slides flex transition-transform duration-500" :style="{ transform: `translateX(-${currentSlide * 100}%)` }">
<div v-for="(slide, index) in carouselItems" :key="index" class="carousel-slide w-full flex-shrink-0">
<div class="grid grid-cols-1 md:grid-cols-2 bg-white dark:bg-gray-800">
<div class="p-8 flex flex-col justify-center">
<h3 class="text-xl md:text-2xl font-bold mb-4 text-primary dark:text-primary-light">{{ slide.title }}</h3>
<p class="text-gray-600 dark:text-gray-300 mb-6">{{ slide.description }}</p>
<NuxtLink :to="slide.link" class="inline-flex items-center text-primary dark:text-primary-light hover:underline">
{{ t('common.learnMore') }} <i class="fas fa-arrow-right ml-2"></i>
</NuxtLink>
</div>
<div class="carousel-image h-60 md:h-auto">
<img :src="slide.image" :alt="slide.title" class="w-full h-full object-cover">
</div>
</div>
</div>
</div>
<!-- 轮播控制按钮 -->
<button @click="prevSlide" class="carousel-control absolute left-2 top-1/2 transform -translate-y-1/2 bg-white/70 dark:bg-gray-800/70 hover:bg-white dark:hover:bg-gray-800 text-primary dark:text-primary-light rounded-full w-10 h-10 flex items-center justify-center">
<i class="fas fa-chevron-left"></i>
</button>
<button @click="nextSlide" class="carousel-control absolute right-2 top-1/2 transform -translate-y-1/2 bg-white/70 dark:bg-gray-800/70 hover:bg-white dark:hover:bg-gray-800 text-primary dark:text-primary-light rounded-full w-10 h-10 flex items-center justify-center">
<i class="fas fa-chevron-right"></i>
</button>
<!-- 轮播指示器 -->
<div class="carousel-indicators flex justify-center mt-4 gap-2 absolute bottom-4 left-1/2 transform -translate-x-1/2">
<button
v-for="(_, index) in carouselItems"
:key="index"
@click="goToSlide(index)"
class="w-2 h-2 rounded-full transition-all duration-300"
:class="index === currentSlide ? 'bg-primary dark:bg-primary-light w-4' : 'bg-gray-300 dark:bg-gray-600'"
></button>
</div>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { useRoute } from "vue-router";
import { useI18n } from "vue-i18n";
import { ref, onMounted, onBeforeUnmount } from 'vue';
import { useHead } from 'nuxt/app';
const route = useRoute();
const lang = route.params.lang || "zh";
const { t } = useI18n();
// 添加页面元数据
useHead({
title: () => t('meta.tag.title'),
meta: [
{ name: 'description', content: () => t('meta.tag.description') },
{ name: 'keywords', content: () => t('meta.tag.keywords') }
]
});
// 轮播图状态
const currentSlide = ref(0);
const autoPlayInterval = ref<any>(null);
// 轮播图控制方法
const nextSlide = () => {
currentSlide.value = (currentSlide.value + 1) % carouselItems.value.length;
};
const prevSlide = () => {
currentSlide.value = (currentSlide.value - 1 + carouselItems.value.length) % carouselItems.value.length;
};
const goToSlide = (index: number) => {
currentSlide.value = index;
};
// 自动播放
const startAutoPlay = () => {
autoPlayInterval.value = setInterval(() => {
nextSlide();
}, 5000);
};
const stopAutoPlay = () => {
if (autoPlayInterval.value) {
clearInterval(autoPlayInterval.value);
}
};
// 生命周期钩子
onMounted(() => {
startAutoPlay();
});
onBeforeUnmount(() => {
stopAutoPlay();
});
const tags = [
"ec2",
"s3",
"rds",
"lambda",
"emr",
"sagemaker",
"waf",
"autoscaling",
"cloudfront",
"dynamodb",
"cloudwatch",
"sns",
"sqs",
"route53",
"elasticache",
"redshift",
];
const navlist = [
{ key: "home", path: "" },
{ key: "products", path: "/products" },
{ key: "solutions", path: "/solutions" },
{ key: "cases", path: "/cases" },
{ key: "news", path: "/awsnews" },
{ key: "about", path: "/about" },
{ key: "contact", path: "/contact" },
];
const pictures = [
'https://picsum.photos/640/640?random=1',
'https://picsum.photos/640/640?random=2',
'https://picsum.photos/640/640?random=3',
'https://picsum.photos/640/640?random=4',
'https://picsum.photos/640/640?random=5',
'https://picsum.photos/640/640?random=6'
];
// 轮播图内容
const carouselItems = ref([
{
title: t('aws.carousel.ec2.title'),
description: t('aws.carousel.ec2.description'),
image: 'https://picsum.photos/640/480?random=1',
link: '/zh/tag/ec2'
},
{
title: t('aws.carousel.s3.title'),
description: t('aws.carousel.s3.description'),
image: 'https://picsum.photos/640/480?random=2',
link: '/zh/tag/s3'
},
{
title: t('aws.carousel.lambda.title'),
description: t('aws.carousel.lambda.description'),
image: 'https://picsum.photos/640/480?random=3',
link: '/zh/tag/lambda'
},
{
title: t('aws.carousel.rds.title'),
description: t('aws.carousel.rds.description'),
image: 'https://picsum.photos/640/480?random=4',
link: '/zh/tag/rds'
}
]);
</script>
<style scoped>
.carousel-container {
height: 400px;
}
@media (max-width: 768px) {
.carousel-container {
height: auto;
}
}
.carousel-control {
opacity: 0.7;
transition: opacity 0.3s ease;
}
.carousel-control:hover {
opacity: 1;
}
:root {
--primary-light: #6fcfff;
}
/* 暗黑模式下的主题色亮变量,可根据实际项目调整 */
.dark .text-primary-light {
color: var(--primary-light);
}
.dark .border-primary-light {
border-color: var(--primary-light);
}
</style>