兴蜀大屏轮播组件部分提交

This commit is contained in:
2025-09-18 15:58:57 +08:00
parent e79759e000
commit dd19b3ee22
19 changed files with 1119 additions and 330 deletions

View File

@ -1,68 +1,62 @@
<template>
<div class="swiper-container">
<div class="swiper-wrapper">
<div
class="swiper-slide"
:class="getSlideClass(index)"
v-for="(slide, index) in slides"
:key="index"
:style="getSlideStyle(index)"
>
<div class="swiper-slide">
<!-- 使用具名插槽传递每个slide的内容和索引 -->
<div class="slide-content">
<div class="slide-image">
<slot name="slide" :slide="slide" :index="index" />
<slot name="slide" />
</div>
<!-- <div class="slide-text">-->
<!-- <h3>{{ slide.title }}</h3>-->
<!-- <p>{{ slide.description }}</p>-->
<!-- </div>-->
<!-- <div class="slide-text">
<h3>{{ slide.title }}</h3>
<p>{{ slide.description }}</p>
</div> -->
</div>
</div>
</div>
<!-- <div class="swiper-controls">-->
<!-- <button class="swiper-button" @click="prevSlide"></button>-->
<!-- <button class="swiper-button" @click="nextSlide"></button>-->
<!-- </div>-->
<!-- <div class="swiper-controls">
<button class="swiper-button" @click="prevSlide"></button>
<button class="swiper-button" @click="nextSlide"></button>
</div> -->
<!-- <div class="swiper-pagination">-->
<!-- <div-->
<!-- class="pagination-bullet"-->
<!-- v-for="(slide, index) in slides"-->
<!-- :key="index"-->
<!-- :class="{ active: currentIndex === index }"-->
<!-- @click="goToSlide(index)"-->
<!-- ></div>-->
<!-- </div>-->
<!-- <div class="swiper-pagination">
<div
class="pagination-bullet"
v-for="(slide, index) in slides"
:key="index"
:class="{ active: currentIndex === index }"
@click="goToSlide(index)"
></div>
</div> -->
</div>
</template>
<script>
import { defineComponent, onMounted, onBeforeUnmount, ref } from 'vue'
import { defineComponent, onMounted, onBeforeUnmount, ref } from "vue";
export default defineComponent({
name: 'Carousel',
name: "Carousel",
props: {
slides: {
type: Array,
required: true,
default: () => [
{
title: '左侧卡片',
description: '淡入效果从左侧进入',
image: 'https://via.placeholder.com/600x400/3498db/ffffff?text=Left'
},
{
title: '中间卡片',
description: '淡入效果居中放大',
image: 'https://via.placeholder.com/600x400/e74c3c/ffffff?text=Center'
},
{
title: '右侧卡片',
description: '淡入效果从右侧进入',
image: 'https://via.placeholder.com/600x400/2ecc71/ffffff?text=Right'
title: "左侧卡片",
description: "淡入效果从左侧进入",
image: "https://via.placeholder.com/600x400/3498db/ffffff?text=Left"
}
// {
// title: "中间卡片",
// description: "淡入效果居中放大",
// image: "https://via.placeholder.com/600x400/e74c3c/ffffff?text=Center"
// },
// {
// title: "右侧卡片",
// description: "淡入效果从右侧进入",
// image: "https://via.placeholder.com/600x400/2ecc71/ffffff?text=Right"
// }
]
},
autoPlayInterval: {
@ -71,62 +65,71 @@ export default defineComponent({
}
},
setup(props) {
const currentIndex = ref(0)
const autoPlayTimer = ref(null)
const currentIndex = ref(0);
const autoPlayTimer = ref(null);
const getSlideClass = (index) => {
const diff = index - currentIndex.value
if (diff === 0) return 'center'
if (diff === -1 || (currentIndex.value === 0 && index === props.slides.length - 1)) return 'left'
if (diff === 1 || (currentIndex.value === props.slides.length - 1 && index === 0)) return 'right'
return ''
}
const diff = index - currentIndex.value;
if (diff === 0) return "center";
if (
diff === -1 ||
(currentIndex.value === 0 && index === props.slides.length - 1)
)
return "left";
if (
diff === 1 ||
(currentIndex.value === props.slides.length - 1 && index === 0)
)
return "right";
return "";
};
const getSlideStyle = (index) => {
const diff = index - currentIndex.value
const diff = index - currentIndex.value;
if (
Math.abs(diff) > 1 &&
!(currentIndex.value === 0 && index === props.slides.length - 1) &&
!(currentIndex.value === props.slides.length - 1 && index === 0)
) {
return { display: 'none' }
return { display: "none" };
}
return {}
}
return {};
};
const prevSlide = () => {
currentIndex.value = (currentIndex.value - 1 + props.slides.length) % props.slides.length
resetAutoPlay()
}
currentIndex.value =
(currentIndex.value - 1 + props.slides.length) % props.slides.length;
resetAutoPlay();
};
const nextSlide = () => {
currentIndex.value = (currentIndex.value + 1) % props.slides.length
resetAutoPlay()
}
currentIndex.value = (currentIndex.value + 1) % props.slides.length;
resetAutoPlay();
};
const goToSlide = (index) => {
currentIndex.value = index
resetAutoPlay()
}
currentIndex.value = index;
resetAutoPlay();
};
const startAutoPlay = () => {
pauseAutoPlay()
pauseAutoPlay();
autoPlayTimer.value = window.setInterval(() => {
nextSlide()
}, props.autoPlayInterval)
}
nextSlide();
}, props.autoPlayInterval);
};
const pauseAutoPlay = () => {
if (autoPlayTimer.value) {
clearInterval(autoPlayTimer.value)
autoPlayTimer.value = null
clearInterval(autoPlayTimer.value);
autoPlayTimer.value = null;
}
}
};
const resetAutoPlay = () => {
pauseAutoPlay()
startAutoPlay()
}
pauseAutoPlay();
startAutoPlay();
};
onMounted(() => {
// const container = document.querySelector('.swiper-container')
@ -135,16 +138,16 @@ export default defineComponent({
// container.addEventListener('mouseleave', startAutoPlay)
// }
// startAutoPlay()
})
});
onBeforeUnmount(() => {
const container = document.querySelector('.swiper-container')
const container = document.querySelector(".swiper-container");
if (container) {
container.removeEventListener('mouseenter', pauseAutoPlay)
container.removeEventListener('mouseleave', startAutoPlay)
container.removeEventListener("mouseenter", pauseAutoPlay);
container.removeEventListener("mouseleave", startAutoPlay);
}
pauseAutoPlay()
})
pauseAutoPlay();
});
return {
currentIndex,
@ -153,9 +156,9 @@ export default defineComponent({
prevSlide,
nextSlide,
goToSlide
}
};
}
})
});
</script>
<style scoped>
@ -168,13 +171,13 @@ export default defineComponent({
.swiper-container {
width: 17.03125vw;
position: relative;
//padding: 2.083vw 0;
/* padding: 2.083vw 0; */
}
.swiper-wrapper {
display: flex;
position: relative;
//height: 400px;
/* height: 400px; */
}
.swiper-slide {