用VUE代码实现轮播图播放效果

12人浏览 / 0人评论 / 添加收藏

Vue轮播图组件实现

我将创建一个美观、功能完整的Vue轮播图组件,包含自动播放、手动切换和指示器功能。

设计思路

使用Vue 3 Composition API

响应式设计,适配不同设备

添加平滑过渡动画

实现自动播放、手动切换和指示器功能

最终实现代码

<!DOCTYPE html>
<html lang="zh-CN">
<head>
   <meta charset="UTF-8">
   <meta name="viewport" content="width=device-width, initial-scale=1.0">
   <title>Vue轮播图组件</title>
   <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
   <style>
       * {
           margin: 0;
           padding: 0;
           box-sizing: border-box;
           font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
       }
       
       body {
           display: flex;
           justify-content: center;
           align-items: center;
           min-height: 100vh;
           background: linear-gradient(135deg, #6a11cb 0%, #2575fc 100%);
           padding: 20px;
       }
       
       .carousel-container {
           width: 100%;
           max-width: 900px;
           position: relative;
           overflow: hidden;
           border-radius: 15px;
           box-shadow: 0 15px 30px rgba(0, 0, 0, 0.3);
       }
       
       .carousel {
           display: flex;
           transition: transform 0.5s ease-in-out;
       }
       
       .slide {
           min-width: 100%;
           position: relative;
       }
       
       .slide img {
           width: 100%;
           display: block;
           height: 450px;
           object-fit: cover;
       }
       
       .slide-content {
           position: absolute;
           bottom: 0;
           left: 0;
           right: 0;
           background: linear-gradient(transparent, rgba(0, 0, 0, 0.8));
           color: white;
           padding: 30px 20px 20px;
       }
       
       .slide-content h3 {
           font-size: 24px;
           margin-bottom: 10px;
       }
       
       .slide-content p {
           font-size: 16px;
           opacity: 0.9;
       }
       
       .carousel-controls {
           position: absolute;
           top: 50%;
           width: 100%;
           display: flex;
           justify-content: space-between;
           transform: translateY(-50%);
           padding: 0 15px;
       }
       
       .carousel-btn {
           background: rgba(255, 255, 255, 0.7);
           border: none;
           width: 45px;
           height: 45px;
           border-radius: 50%;
           cursor: pointer;
           display: flex;
           justify-content: center;
           align-items: center;
           font-size: 20px;
           color: #333;
           transition: all 0.3s ease;
           box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2);
       }
       
       .carousel-btn:hover {
           background: white;
           transform: scale(1.1);
       }
       
       .carousel-indicators {
           position: absolute;
           bottom: 20px;
           width: 100%;
           display: flex;
           justify-content: center;
           gap: 10px;
       }
       
       .indicator {
           width: 12px;
           height: 12px;
           border-radius: 50%;
           background: rgba(255, 255, 255, 0.5);
           cursor: pointer;
           transition: all 0.3s ease;
       }
       
       .indicator.active {
           background: white;
           transform: scale(1.2);
       }
       
       .auto-play-toggle {
           position: absolute;
           top: 20px;
           right: 20px;
           background: rgba(255, 255, 255, 0.7);
           border: none;
           padding: 8px 15px;
           border-radius: 20px;
           cursor: pointer;
           font-size: 14px;
           font-weight: 600;
           transition: all 0.3s ease;
           display: flex;
           align-items: center;
           gap: 5px;
       }
       
       .auto-play-toggle:hover {
           background: white;
       }
       
       @media (max-width: 768px) {
           .slide img {
               height: 350px;
           }
           
           .slide-content h3 {
               font-size: 20px;
           }
           
           .slide-content p {
               font-size: 14px;
           }
       }
       
       @media (max-width: 480px) {
           .slide img {
               height: 250px;
           }
           
           .carousel-btn {
               width: 35px;
               height: 35px;
               font-size: 16px;
           }
           
           .slide-content {
               padding: 20px 15px 15px;
           }
       }
   </style>
</head>
<body>
   <div id="app">
       <div class="carousel-container">
           <div class="carousel" :style="{ transform: `translateX(-${currentIndex * 100}%)` }">
               <div class="slide" v-for="(slide, index) in slides" :key="index">
                   <img :src="slide.image" :alt="slide.title">
                   <div class="slide-content">
                       <h3>{{ slide.title }}</h3>
                       <p>{{ slide.description }}</p>
                   </div>
               </div>
           </div>
           
           <div class="carousel-controls">
               <button class="carousel-btn prev-btn" @click="prevSlide">❮</button>
               <button class="carousel-btn next-btn" @click="nextSlide">❯</button>
           </div>
           
           <div class="carousel-indicators">
               <div 
                   class="indicator" 
                   v-for="(slide, index) in slides" 
                   :key="index"
                   :class="{ active: index === currentIndex }"
                   @click="goToSlide(index)"
               ></div>
           </div>
           
           <button class="auto-play-toggle" @click="toggleAutoPlay">
               <span class="play-icon">{{ isAutoPlaying ? '❚❚' : '▶' }}</span>
               <span class="toggle-text">{{ isAutoPlaying ? '暂停' : '播放' }}</span>
           </button>
       </div>
   </div>

   <script>
       const { createApp, ref, onMounted, onUnmounted } = Vue;
       
       createApp({
           setup() {
               const slides = ref([
                   {
                       image: 'https://images.unsplash.com/photo-1506744038136-46273834b3fb',
                       title: '美丽的自然风光',
                       description: '探索世界上最令人惊叹的自然奇观,感受大自然的魅力。'
                   },
                   {
                       image: 'https://images.unsplash.com/photo-1470071459604-3b5ec3a7fe05',
                       title: '壮丽的山脉',
                       description: '高耸入云的山峰,云雾缭绕的景色,令人心旷神怡。'
                   },
                   {
                       image: 'https://images.unsplash.com/photo-1469474968028-56623f02e42e',
                       title: '神秘的森林',
                       description: '深入茂密的森林,发现隐藏其中的自然奥秘。'
                   },
                   {
                       image: 'https://images.unsplash.com/photo-1439066615861-d1af74d74000',
                       title: '宁静的湖泊',
                       description: '清澈见底的湖水,倒映着蓝天白云,宛如人间仙境。'
                   }
               ]);
               
               const currentIndex = ref(0);
               const isAutoPlaying = ref(true);
               let autoPlayInterval = null;
               
               // 下一张幻灯片
               const nextSlide = () => {
                   currentIndex.value = (currentIndex.value + 1) % slides.value.length;
               };
               
               // 上一张幻灯片
               const prevSlide = () => {
                   currentIndex.value = (currentIndex.value - 1 + slides.value.length) % slides.value.length;
               };
               
               // 跳转到指定幻灯片
               const goToSlide = (index) => {
                   currentIndex.value = index;
                   // 重置自动播放
                   if (isAutoPlaying.value) {
                       stopAutoPlay();
                       startAutoPlay();
                   }
               };
               
               // 开始自动播放
               const startAutoPlay = () => {
                   autoPlayInterval = setInterval(nextSlide, 4000);
                   isAutoPlaying.value = true;
               };
               
               // 停止自动播放
               const stopAutoPlay = () => {
                   clearInterval(autoPlayInterval);
                   isAutoPlaying.value = false;
               };
               
               // 切换自动播放状态
               const toggleAutoPlay = () => {
                   if (isAutoPlaying.value) {
                       stopAutoPlay();
                   } else {
                       startAutoPlay();
                   }
               };
               
               // 鼠标悬停时暂停自动播放
               const handleMouseEnter = () => {
                   if (isAutoPlaying.value) {
                       stopAutoPlay();
                   }
               };
               
               // 鼠标离开时恢复自动播放
               const handleMouseLeave = () => {
                   if (isAutoPlaying.value) {
                       startAutoPlay();
                   }
               };
               
               // 组件挂载后开始自动播放
               onMounted(() => {
                   startAutoPlay();
                   
                   // 添加鼠标事件监听
                   const carouselContainer = document.querySelector('.carousel-container');
                   carouselContainer.addEventListener('mouseenter', handleMouseEnter);
                   carouselContainer.addEventListener('mouseleave', handleMouseLeave);
               });
               
               // 组件卸载前清除定时器
               onUnmounted(() => {
                   stopAutoPlay();
                   
                   // 移除事件监听
                   const carouselContainer = document.querySelector('.carousel-container');
                   carouselContainer.removeEventListener('mouseenter', handleMouseEnter);
                   carouselContainer.removeEventListener('mouseleave', handleMouseLeave);
               });
               
               return {
                   slides,
                   currentIndex,
                   isAutoPlaying,
                   nextSlide,
                   prevSlide,
                   goToSlide,
                   toggleAutoPlay
               };
           }
       }).mount('#app');
   </script>
</body>
</html>

效果如下:

功能说明

自动播放:轮播图默认每4秒自动切换

手动控制

左右箭头按钮可手动切换

底部指示器可直接跳转到指定幻灯片

播放控制

右上角按钮可暂停/播放自动切换

鼠标悬停时自动暂停播放

响应式设计:适配不同屏幕尺寸

平滑过渡:使用CSS过渡实现流畅的切换效果

Vue组件特点

使用Vue 3 Composition API:代码结构清晰,逻辑复用方便

响应式数据:使用ref和reactive管理状态

生命周期钩子:使用onMounted和onUnmounted管理自动播放

事件处理:使用Vue的事件绑定语法

使用说明

将代码复制到HTML文件中直接运行

修改slides数组中的内容以自定义轮播图

可根据需要调整CSS样式和JavaScript参数

这个Vue轮播图组件设计美观、功能完整,可以直接使用或根据需要进行定制。

全部评论