vue实现纵向轮播
Vue 实现纵向轮播
纵向轮播可以通过 CSS 动画和 Vue 的动态数据绑定实现。以下是一个基于 Vue 3 的实现方案。
基本结构
使用 Vue 的 transition-group 和 CSS 过渡效果实现纵向滚动效果。
<template>
<div class="carousel-container">
<div class="carousel-wrapper" ref="wrapper">
<transition-group name="slide" tag="div">
<div class="carousel-item" v-for="(item, index) in items" :key="index">
{{ item }}
</div>
</transition-group>
</div>
</div>
</template>
数据与样式
定义轮播数据项和基本样式,确保内容纵向排列。
<script>
export default {
data() {
return {
items: ["Item 1", "Item 2", "Item 3", "Item 4"],
currentIndex: 0,
};
},
};
</script>
<style>
.carousel-container {
height: 200px;
overflow: hidden;
position: relative;
}
.carousel-wrapper {
height: 100%;
}
.carousel-item {
height: 200px;
display: flex;
align-items: center;
justify-content: center;
background: #f0f0f0;
margin-bottom: 10px;
}
.slide-enter-active,
.slide-leave-active {
transition: all 0.5s ease;
}
.slide-enter-from {
transform: translateY(100%);
}
.slide-leave-to {
transform: translateY(-100%);
}
</style>
自动轮播逻辑
通过 setInterval 实现自动轮播,动态更新 currentIndex 并处理边界条件。
<script>
export default {
data() {
return {
items: ["Item 1", "Item 2", "Item 3", "Item 4"],
currentIndex: 0,
interval: null,
};
},
mounted() {
this.startAutoPlay();
},
beforeUnmount() {
this.stopAutoPlay();
},
methods: {
startAutoPlay() {
this.interval = setInterval(() => {
this.currentIndex = (this.currentIndex + 1) % this.items.length;
}, 3000);
},
stopAutoPlay() {
clearInterval(this.interval);
},
},
};
</script>
动态绑定
将 currentIndex 与轮播项的位置绑定,通过 CSS 控制偏移实现平滑滚动。
<template>
<div class="carousel-container">
<div class="carousel-wrapper" ref="wrapper">
<div
class="carousel-inner"
:style="{ transform: `translateY(-${currentIndex * 100}%)` }"
>
<div class="carousel-item" v-for="(item, index) in items" :key="index">
{{ item }}
</div>
</div>
</div>
</div>
</template>
<style>
.carousel-inner {
transition: transform 0.5s ease;
}
</style>
手势支持
添加触摸事件支持,提升移动端体验。
<script>
export default {
methods: {
handleTouchStart(e) {
this.startY = e.touches[0].clientY;
},
handleTouchMove(e) {
this.deltaY = e.touches[0].clientY - this.startY;
},
handleTouchEnd() {
if (this.deltaY > 50) {
this.currentIndex = Math.max(0, this.currentIndex - 1);
} else if (this.deltaY < -50) {
this.currentIndex = Math.min(this.items.length - 1, this.currentIndex + 1);
}
this.deltaY = 0;
},
},
};
</script>
完整示例
整合以上功能,实现完整的纵向轮播组件。

<template>
<div
class="carousel-container"
@touchstart="handleTouchStart"
@touchmove="handleTouchMove"
@touchend="handleTouchEnd"
>
<div class="carousel-wrapper" ref="wrapper">
<div
class="carousel-inner"
:style="{ transform: `translateY(-${currentIndex * 100}%)` }"
>
<div class="carousel-item" v-for="(item, index) in items" :key="index">
{{ item }}
</div>
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
items: ["Item 1", "Item 2", "Item 3", "Item 4"],
currentIndex: 0,
interval: null,
startY: 0,
deltaY: 0,
};
},
mounted() {
this.startAutoPlay();
},
beforeUnmount() {
this.stopAutoPlay();
},
methods: {
startAutoPlay() {
this.interval = setInterval(() => {
this.currentIndex = (this.currentIndex + 1) % this.items.length;
}, 3000);
},
stopAutoPlay() {
clearInterval(this.interval);
},
handleTouchStart(e) {
this.startY = e.touches[0].clientY;
},
handleTouchMove(e) {
this.deltaY = e.touches[0].clientY - this.startY;
},
handleTouchEnd() {
if (this.deltaY > 50) {
this.currentIndex = Math.max(0, this.currentIndex - 1);
} else if (this.deltaY < -50) {
this.currentIndex = Math.min(this.items.length - 1, this.currentIndex + 1);
}
this.deltaY = 0;
},
},
};
</script>
<style>
.carousel-container {
height: 200px;
overflow: hidden;
position: relative;
}
.carousel-wrapper {
height: 100%;
}
.carousel-inner {
transition: transform 0.5s ease;
}
.carousel-item {
height: 200px;
display: flex;
align-items: center;
justify-content: center;
background: #f0f0f0;
}
</style>






