76 lines
2.1 KiB
Vue
76 lines
2.1 KiB
Vue
<!-- 模块内容轮播:没有有效图片时不渲染,也不保留占位。 -->
|
||
<template>
|
||
<div v-if="visibleBanners.length" class="module-banners" @touchstart.stop @touchmove.stop @touchend.stop>
|
||
<van-swipe :key="bannerKey" :autoplay="visibleBanners.length > 1 ? 5000 : 0">
|
||
<van-swipe-item v-for="(banner, index) in visibleBanners" :key="index" @click="openContent(banner)">
|
||
<LazyImg :src="banner.image" />
|
||
</van-swipe-item>
|
||
</van-swipe>
|
||
</div>
|
||
</template>
|
||
<script setup lang="ts">
|
||
import { computed } from 'vue';
|
||
import { useRouter } from 'vue-router';
|
||
import { getModuleBannerTarget } from '@/utils/moduleBanner';
|
||
|
||
const props = defineProps<{
|
||
banners?: Types.Home.ModuleBanner[] | null;
|
||
moduleType: number;
|
||
imageFit?: 'cover' | 'contain';
|
||
}>();
|
||
const router = useRouter();
|
||
const visibleBanners = computed(() =>
|
||
Array.isArray(props.banners) ? props.banners.filter((banner) => banner?.image?.trim()) : [],
|
||
);
|
||
const bannerKey = computed(() => visibleBanners.value.map((banner) => `${banner.contentId}:${banner.image}`).join('|'));
|
||
const openContent = (banner: Types.Home.ModuleBanner) => {
|
||
const target = getModuleBannerTarget(props.moduleType, banner.contentId);
|
||
if (target) void router.push(target);
|
||
};
|
||
</script>
|
||
<style scoped lang="scss">
|
||
.module-banners {
|
||
padding: 12px 16px;
|
||
.van-swipe {
|
||
width: 100%;
|
||
height: 193px;
|
||
border-radius: 12px;
|
||
}
|
||
.van-swipe-item::after {
|
||
content: '';
|
||
position: absolute;
|
||
right: 0;
|
||
bottom: 0;
|
||
left: 0;
|
||
height: 50px;
|
||
background: linear-gradient(to bottom, transparent, #000);
|
||
pointer-events: none;
|
||
}
|
||
:deep(.img-decypt) {
|
||
width: 100%;
|
||
height: 100%;
|
||
}
|
||
:deep(.van-swipe__indicators) {
|
||
transform: translateX(0);
|
||
left: auto;
|
||
right: 12px;
|
||
bottom: 12px;
|
||
.van-swipe__indicator {
|
||
width: 4px;
|
||
height: 4px;
|
||
border-radius: 3px;
|
||
background: rgba(255, 255, 255, 0.6);
|
||
opacity: 0.3;
|
||
&:not(:last-child) {
|
||
margin-right: 4px;
|
||
}
|
||
}
|
||
.van-swipe__indicator--active {
|
||
width: 12px;
|
||
background: $themeColor;
|
||
opacity: 1;
|
||
}
|
||
}
|
||
}
|
||
</style>
|