refactor: 将首页各个部分重构为单独的组件

- 组件重构:将首页重构为HomepageCarousel, HomepageProductSection,
HomepageSolutionSection三个部分
This commit is contained in:
2025-10-29 14:05:42 +08:00
parent 300266d32c
commit 5920925ded
4 changed files with 447 additions and 291 deletions

View File

@ -0,0 +1,176 @@
<template>
<section class="homepage-section">
<h2>推荐解决方案</h2>
<p>了解我们的定制解决方案帮助您优化业务流程提高效率</p>
<div v-if="!pending">
<el-carousel
class="recommend-carousel"
height="auto"
arrow="never"
indicator-position="outside"
:autoplay="false"
>
<el-carousel-item
v-for="n in Math.floor(solutions.length / 3) + 1"
:key="n"
class="recommend-list"
>
<div class="recommend-card-group">
<el-card
v-for="(item, index) in solutions.slice((n - 1) * 3, n * 3)"
:key="index"
class="recommend-card"
@click="handleSolutionCardClick(item.id.toString() || '')"
>
<template #header>
<el-image
:src="getImageUrl(item.cover)"
:alt="item.title"
fit="cover"
lazy
/>
</template>
<div class="recommend-card-body">
<!-- Title -->
<div class="text-center">
<span class="recommend-card-title">{{ item.title }}</span>
</div>
<!-- Description -->
<div class="recommend-card-description text-left opacity-25">
{{ item.summary }}
</div>
</div>
</el-card>
</div>
</el-carousel-item>
</el-carousel>
</div>
<div v-else>
<el-skeleton :rows="4" animated />
</div>
</section>
</template>
<script setup lang="ts">
const props = defineProps({
homepageData: {
type: Object as PropType<HomepageView>,
default: null,
},
pending: {
type: Boolean,
},
});
const { getImageUrl } = useDirectusImage();
const solutions = computed(
() => props.homepageData?.recommendSolutions || []
);
const handleSolutionCardClick = (documentId: string) => {
// 使用路由导航到产品详情页
if (documentId) {
const localePath = useLocalePath();
const router = useRouter();
router.push(localePath(`/solutions/${documentId}`));
}
};
</script>
<style scoped>
section {
padding: 2rem;
}
section h2 {
color: var(--el-text-color-primary);
font-size: 1.5rem;
font-weight: bold;
margin-bottom: 0.5rem;
}
section p {
color: var(--el-text-color-regular);
line-height: 1.6;
}
.homepage-section {
max-width: 1200px;
margin: 0 auto;
}
.recommend-carousel :deep(.el-carousel__button) {
/* 指示器按钮样式 */
width: 8px;
height: 8px;
border-radius: 50%;
background-color: #475669;
transition: all 0.3s ease;
}
.homepage-section {
max-width: 1200px;
margin: 0 auto;
}
.recommend-carousel :deep(.el-carousel__button) {
/* 指示器按钮样式 */
width: 8px;
height: 8px;
border-radius: 50%;
background-color: #475669;
transition: all 0.3s ease;
}
.recommend-list {
display: flex;
padding: 1rem;
height: 400px;
}
.recommend-card-group {
display: flex;
gap: 1rem;
width: 100%;
margin: 0 auto;
height: 100%;
}
.recommend-card {
width: 33%;
transition: all 0.3s ease;
text-align: center;
}
.recommend-card :deep(.el-card__header) {
padding: 0;
border: none;
}
.recommend-card:hover {
transform: translateY(-4px);
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.15);
cursor: pointer;
}
.recommend-card-body {
margin: 10px auto;
padding: 0px auto;
}
.recommend-card-title {
font-size: 1rem;
font-weight: 600;
}
.recommend-card-description {
font-size: 0.8rem;
margin-top: 5px;
}
.recommend-card .el-image {
width: 100%;
border-radius: 4px;
}
</style>