轮播图可以预览

This commit is contained in:
yml2213
2026-07-23 18:28:35 +08:00
parent 9d74cbcf8d
commit 1ea01f7d46
3 changed files with 71 additions and 4 deletions
@@ -1,4 +1,6 @@
<script setup lang="ts">
import { computed, ref } from 'vue'
interface HomeBannerSlide {
title?: string
eyebrow?: string
@@ -12,14 +14,43 @@ interface Props {
banners: HomeBannerSlide[]
}
defineProps<Props>()
const props = defineProps<Props>()
const previewVisible = ref(false)
const previewIndex = ref(0)
const previewUrls = computed(() =>
props.banners
.map(slide => slide.image_url?.trim() || '')
.filter((url): url is string => Boolean(url))
)
function openPreview(slide: HomeBannerSlide) {
const url = slide.image_url?.trim()
if (!url) return
const index = previewUrls.value.indexOf(url)
if (index < 0) return
previewIndex.value = index
previewVisible.value = true
}
function closePreview() {
previewVisible.value = false
}
</script>
<template>
<section class="hero-board">
<el-carousel height="240px" indicator-position="outside" :interval="3600">
<el-carousel-item v-for="slide in banners" :key="slide.title || slide.image_url">
<div class="hero-slide" :class="[`tone-${slide.tone}`, { 'has-image': slide.image_url }]">
<div
class="hero-slide"
:class="[
`tone-${slide.tone}`,
{ 'has-image': slide.image_url, 'is-previewable': !!slide.image_url },
]"
@click="openPreview(slide)"
>
<img
v-if="slide.image_url"
:src="slide.image_url"
@@ -34,6 +65,15 @@ defineProps<Props>()
</div>
</el-carousel-item>
</el-carousel>
<el-image-viewer
v-if="previewVisible"
:url-list="previewUrls"
:initial-index="previewIndex"
teleported
hide-on-click-modal
@close="closePreview"
/>
</section>
</template>
@@ -69,6 +109,10 @@ defineProps<Props>()
background: linear-gradient(135deg, #eff6ff 0%, #ffffff 58%, #fff7ed 100%);
}
.hero-slide.is-previewable {
cursor: zoom-in;
}
.hero-slide.tone-blue {
background: linear-gradient(135deg, #eff6ff 0%, #dbeafe 56%, #fff7ed 100%);
}