feat: 首页竖屏适配

- 首页Carousel高度根据屏幕宽度变化
- 首页推荐栏目卡片数量随屏幕宽度改变
This commit is contained in:
2025-11-01 15:32:15 +08:00
parent 06c30a7ea3
commit d076088747
3 changed files with 119 additions and 10 deletions

View File

@ -83,4 +83,10 @@
border-radius: 5px; border-radius: 5px;
font-size: 14px; font-size: 14px;
} }
@media (max-width: 768px) {
.homepage-carousel .el-carousel__item {
height: 50vw;
}
}
</style> </style>

View File

@ -7,19 +7,20 @@
<div v-if="!pending"> <div v-if="!pending">
<el-carousel <el-carousel
class="recommend-carousel" class="recommend-carousel"
height="auto" :height="carouselHeight"
arrow="never" arrow="never"
indicator-position="outside" indicator-position="outside"
:autoplay="false" :autoplay="false"
> >
<el-carousel-item <el-carousel-item
v-for="n in Math.floor(products.length / 3) + 1" v-for="n in pages"
ref="carouselItem"
:key="n" :key="n"
class="recommend-list" class="recommend-list"
> >
<div class="recommend-card-group"> <div class="recommend-card-group">
<el-card <el-card
v-for="(item, index) in products.slice((n - 1) * 3, n * 3)" v-for="(item, index) in pageProducts(n)"
:key="index" :key="index"
class="recommend-card" class="recommend-card"
@click="handleProductCardClick(item.id.toString() || '')" @click="handleProductCardClick(item.id.toString() || '')"
@ -64,9 +65,32 @@
}, },
}); });
const carouselHeight = ref<string>('auto');
const perPage = ref(3);
const carouselItem = ref<HTMLElement | null>(null);
const { getImageUrl } = useDirectusImage(); const { getImageUrl } = useDirectusImage();
const { height } = useElementSize(carouselItem);
const products = computed(() => props.homepageData?.recommendProducts || []); const products = computed(() => props.homepageData?.recommendProducts || []);
const pages = computed(() =>
Math.ceil(products.value.length / perPage.value)
);
const updatePerPage = () => {
const width = window.innerWidth;
if (width < 768) {
perPage.value = 1;
} else if (width < 1024) {
perPage.value = 2;
} else {
perPage.value = 3;
}
};
const pageProducts = (n: number) => {
return products.value.slice((n - 1) * perPage.value, n * perPage.value);
};
const handleProductCardClick = (documentId: string) => { const handleProductCardClick = (documentId: string) => {
// 使用路由导航到产品详情页 // 使用路由导航到产品详情页
@ -76,6 +100,21 @@
router.push(localePath(`/products/${documentId}`)); router.push(localePath(`/products/${documentId}`));
} }
}; };
watch(height, (h) => {
if (h > 0) {
carouselHeight.value = h + 40 + 'px';
}
});
onMounted(() => {
updatePerPage();
window.addEventListener('resize', updatePerPage);
});
onBeforeUnmount(() => {
window.removeEventListener('resize', updatePerPage);
});
</script> </script>
<style scoped> <style scoped>
@ -126,7 +165,7 @@
.recommend-list { .recommend-list {
display: flex; display: flex;
padding: 1rem; padding: 1rem;
height: 400px; height: auto;
} }
.recommend-card-group { .recommend-card-group {
@ -134,7 +173,7 @@
gap: 1rem; gap: 1rem;
width: 100%; width: 100%;
margin: 0 auto; margin: 0 auto;
height: 100%; height: auto;
} }
.recommend-card { .recommend-card {
@ -173,4 +212,16 @@
width: 100%; width: 100%;
border-radius: 4px; border-radius: 4px;
} }
@media (max-width: 1024px) {
.recommend-card {
width: 50%;
}
}
@media (max-width: 768px) {
.recommend-card {
width: 100%;
}
}
</style> </style>

View File

@ -5,19 +5,20 @@
<div v-if="!pending"> <div v-if="!pending">
<el-carousel <el-carousel
class="recommend-carousel" class="recommend-carousel"
height="auto" :height="carouselHeight"
arrow="never" arrow="never"
indicator-position="outside" indicator-position="outside"
:autoplay="false" :autoplay="false"
> >
<el-carousel-item <el-carousel-item
v-for="n in Math.floor(solutions.length / 3) + 1" v-for="n in pages"
ref="carouselItem"
:key="n" :key="n"
class="recommend-list" class="recommend-list"
> >
<div class="recommend-card-group"> <div class="recommend-card-group">
<el-card <el-card
v-for="(item, index) in solutions.slice((n - 1) * 3, n * 3)" v-for="(item, index) in pageSolutions(n)"
:key="index" :key="index"
class="recommend-card" class="recommend-card"
@click="handleSolutionCardClick(item.id.toString() || '')" @click="handleSolutionCardClick(item.id.toString() || '')"
@ -62,11 +63,34 @@
}, },
}); });
const carouselHeight = ref<string>('auto');
const perPage = ref(3);
const carouselItem = ref<HTMLElement | null>(null);
const { getImageUrl } = useDirectusImage(); const { getImageUrl } = useDirectusImage();
const { height } = useElementSize(carouselItem);
const solutions = computed( const solutions = computed(
() => props.homepageData?.recommendSolutions || [] () => props.homepageData?.recommendSolutions || []
); );
const pages = computed(() =>
Math.ceil(solutions.value.length / perPage.value)
);
const updatePerPage = () => {
const width = window.innerWidth;
if (width < 768) {
perPage.value = 1;
} else if (width < 1024) {
perPage.value = 2;
} else {
perPage.value = 3;
}
};
const pageSolutions = (n: number) => {
return solutions.value.slice((n - 1) * perPage.value, n * perPage.value);
};
const handleSolutionCardClick = (documentId: string) => { const handleSolutionCardClick = (documentId: string) => {
// 使用路由导航到产品详情页 // 使用路由导航到产品详情页
@ -76,6 +100,22 @@
router.push(localePath(`/solutions/${documentId}`)); router.push(localePath(`/solutions/${documentId}`));
} }
}; };
watch(height, (h) => {
if (h > 0) {
carouselHeight.value = h + 40 + 'px';
console.log('carouselHeight updated:', carouselHeight.value);
}
});
onMounted(() => {
updatePerPage();
window.addEventListener('resize', updatePerPage);
});
onBeforeUnmount(() => {
window.removeEventListener('resize', updatePerPage);
});
</script> </script>
<style scoped> <style scoped>
@ -126,7 +166,7 @@
.recommend-list { .recommend-list {
display: flex; display: flex;
padding: 1rem; padding: 1rem;
height: 400px; height: auto;
} }
.recommend-card-group { .recommend-card-group {
@ -134,7 +174,7 @@
gap: 1rem; gap: 1rem;
width: 100%; width: 100%;
margin: 0 auto; margin: 0 auto;
height: 100%; height: auto;
} }
.recommend-card { .recommend-card {
@ -173,4 +213,16 @@
width: 100%; width: 100%;
border-radius: 4px; border-radius: 4px;
} }
@media (max-width: 1024px) {
.recommend-card {
width: 50%;
}
}
@media (max-width: 768px) {
.recommend-card {
width: 100%;
}
}
</style> </style>