vue实现木马轮播图
实现木马轮播图的基本思路
木马轮播图(Carousel)通常指具有3D效果的轮播图,常见于展示图片或卡片。Vue实现的核心在于利用CSS 3D变换和Vue的动态数据绑定,结合动画效果实现视觉上的立体旋转。
安装依赖
确保项目已安装Vue 3。若需动画支持,可安装vueuse或gsap等动画库:
npm install vue @vueuse/core
基础HTML结构
创建一个包含轮播项列表的容器,通过Vue动态渲染项:
<template>
<div class="carousel-container">
<div class="carousel-track" :style="trackStyle">
<div
v-for="(item, index) in items"
:key="index"
class="carousel-item"
:style="getItemStyle(index)"
>
{{ item }}
</div>
</div>
<button @click="prev">Prev</button>
<button @click="next">Next</button>
</div>
</template>
Vue组件逻辑
定义数据和方法控制轮播行为:
<script setup>
import { ref, computed } from 'vue';
const items = ref(['Item 1', 'Item 2', 'Item 3', 'Item 4', 'Item 5']);
const currentIndex = ref(0);
const itemCount = items.value.length;
const trackStyle = computed(() => {
const angle = 360 / itemCount;
return {
transform: `rotateY(${-currentIndex.value * angle}deg)`
};
});
const getItemStyle = (index) => {
const angle = 360 / itemCount;
return {
transform: `rotateY(${index * angle}deg) translateZ(250px)`
};
};
const next = () => {
currentIndex.value = (currentIndex.value + 1) % itemCount;
};
const prev = () => {
currentIndex.value = (currentIndex.value - 1 + itemCount) % itemCount;
};
</script>
CSS样式
通过CSS实现3D视觉效果:
<style>
.carousel-container {
perspective: 1000px;
width: 100%;
height: 300px;
position: relative;
}
.carousel-track {
width: 100%;
height: 100%;
position: relative;
transform-style: preserve-3d;
transition: transform 1s ease;
}
.carousel-item {
position: absolute;
width: 200px;
height: 200px;
background: #f0f0f0;
border: 1px solid #ccc;
display: flex;
align-items: center;
justify-content: center;
transform-origin: center center;
}
</style>
动画优化
使用transition或gsap平滑过渡:
import { gsap } from 'gsap';
const next = () => {
gsap.to('.carousel-track', {
duration: 1,
rotateY: -((currentIndex.value + 1) % itemCount) * (360 / itemCount),
onComplete: () => {
currentIndex.value = (currentIndex.value + 1) % itemCount;
}
});
};
响应式调整
通过监听窗口大小动态调整translateZ值:
import { useWindowSize } from '@vueuse/core';
const { width } = useWindowSize();
const translateZ = computed(() => {
return Math.min(width.value * 0.3, 250);
});
自动轮播
添加定时器实现自动播放:
import { onMounted, onUnmounted } from 'vue';
let interval;
onMounted(() => {
interval = setInterval(next, 3000);
});
onUnmounted(() => {
clearInterval(interval);
});
触摸支持
通过@touchstart和@touchend实现移动端滑动:
<div
class="carousel-track"
@touchstart="handleTouchStart"
@touchend="handleTouchEnd"
>
</div>
const touchStartX = ref(0);
const handleTouchStart = (e) => {
touchStartX.value = e.touches[0].clientX;
};
const handleTouchEnd = (e) => {
const touchEndX = e.changedTouches[0].clientX;
if (touchStartX.value - touchEndX > 50) next();
if (touchEndX - touchStartX.value > 50) prev();
};
无限循环
克隆首尾项实现无缝循环:
const extendedItems = computed(() => {
return [items.value[itemCount - 1], ...items.value, items.value[0]];
});






