轮播图 vue

轮播图

业务

1、点击左右箭头图标,实现图片切换

2、点击底部小圆点时,可切换对应顺序的图片,同时该小圆点高亮

3、实现自动播放(定时器)

4、当鼠标悬停在图片上时,停止自动播放(关闭定时器)

5、当鼠标离开图片时,开启自动播放(开启定时器)

6、组件被销毁时,清除定时器

html

1、结构 ul 包裹 li, li 里通过 router-link 包裹 img

2、调用后端接口请求数据对 li 进行 v-for 循环遍历

3、左右两侧的箭头图标,通过 a 标签,包裹 i 标签,使用子体图标

4、底部小圆点,使用 div 包裹 span ,根据后端返回的数据,对 span 进行 v-for 循环

v-for="(item, i) in sliders",其中 sliders 为后端返回的轮播图详情,

落地代码

 <template>
   <!-- 轮播图组件 -->
   <div class="xtx-carousel" @mouseenter="stop" @mouseleave="start">
     <!-- 轮播图的图片 -->
     <ul class="carousel-body">
       <!-- fade 当前显示的图片的样式 -->
       <li
         class="carousel-item"
         :class="{ fade: index === i }"
         v-for="(item, i) in sliders"
         :key="item.id"
       >
         <RouterLink to="/">
           <img :src="item.imgUrl" alt="" />
         </RouterLink>
       </li>
     </ul>
     <!-- 轮播图的左右切换图标 -->
     <a @click="toggle(-1)" href="javascript:;" class="carousel-btn prev"
       ><i class="iconfont icon-angle-left"></i
     ></a>
     <a @click="toggle(1)" href="javascript:;" class="carousel-btn next"
       ><i class="iconfont icon-angle-right"></i
     ></a>
     <div class="carousel-indicator">
       <!-- 底部小圆点 -->
       <!-- active 当前显示的照片对应的小圆点高亮 -->
       <span
         v-for="(item, i) in sliders"
         :key="item.id"
         :class="{ active: index === i }"
         @click="index = i"
       ></span>
     </div>
   </div>
 </template>

 ​

css

实现轮播图的常用两种方案:

  • 方案1:通过位移的距离,显示当前图片

  • 方案2:通过透明度,当前图片,动态添加类名,实现透明度为 1 ,其余图片透明度为 0

落地代码(方案2)

<style scoped lang="less">
 .xtx-carousel {
   width: 100%;
   height: 100%;
   min-width: 300px;
   min-height: 150px;
   position: relative;
   .carousel {
     &-body {
       width: 100%;
       height: 100%;
     }
     &-item {
       width: 100%;
       height: 100%;
       position: absolute;
       left: 0;
       top: 0;
       opacity: 0;
       transition: opacity 0.5s linear;
       //当前显示的轮播图照片
       &.fade {
         opacity: 1;
         z-index: 1;
       }
       img {
         width: 100%;
         height: 100%;
       }
     }
     &-indicator {
       position: absolute;
       left: 0;
       bottom: 20px;
       z-index: 2;
       width: 100%;
       text-align: center;
       span {
         display: inline-block;
         width: 12px;
         height: 12px;
         background: rgba(0, 0, 0, 0.2);
         border-radius: 50%;
         cursor: pointer;
         ~ span {
           margin-left: 12px;
         }
         // 当前显示照片对应的小圆点
         &.active {
           background: #fff;
         }
       }
     }
     &-btn {
       width: 44px;
       height: 44px;
       background: rgba(0, 0, 0, 0.2);
       color: #fff;
       border-radius: 50%;
       position: absolute;
       top: 228px;
       z-index: 2;
       text-align: center;
       line-height: 44px;
       opacity: 0;
       transition: all 0.5s;
       &.prev {
         left: 20px;
       }
       &.next {
         right: 20px;
       }
     }
   }
   &:hover {
     .carousel-btn {
       opacity: 1;
     }
   }
 }
 </style>
 ​

js

1、点击左右箭头图标,实现图片切换

声明一个变量 index ,用来指定轮播图的默认图片下标

调用接口请求轮播图数据 sliders

铺设数据渲染页面

左右箭头绑定相同事件名称,传入不同的参数,左箭头传入 ( -1 ) ,右箭头传入 ( 1 )

setup 内定义事件并接收形参 i ,当点击时,index.value += i

兜底:

  • 当切换到最右边时,强制将下一张变为第一张 index.value >= sliders.length 时,index.value = 0

  • 当切换到最做左边时,强制将下一张变最后一张 index.value < 0 时,index.value = sliders.length - 1

2、点击底部小圆点时,可切换对应顺序的图片,同时该小圆点高亮

span 绑定点击事件,@click = ' index = i'

高亮样式:动态 :class ='{ 样式名: index===i }'

3、实现自动播放(定时器)

定义定时器函数,每隔 2 秒 , index.value ++ ,但是不能无限++,当 index.value >= sliders.length 时,index.value = 0

同时在每次定时器开始前,先清除一下定时器,原因:防止影响播放顺序

定时器的执行:在侦听器的回调函数中调用该定时器函数,当 sliders 发生变化的时候,就调用该定时器函数

4、当鼠标悬停在图片上时,停止自动播放(关闭定时器)

轮播图的最外层 div 绑定 @mouseenter 事件,当鼠标进入时,清除定时器

5、当鼠标离开图片时,开启自动播放(开启定时器)

轮播图的最外层 div 绑定 @mouseleave 事件,当鼠标进入时,调用定时器函数

6、组件被销毁时,清除定时器

在钩子函数 onUnmounted 内清除定时器

落地代码

 
export default {
   name: 'XtxCarousel',
   props: {
     // 轮播图数据
     sliders: {
       type: Array,
       required: true
     },
     // 是否自动播放
     autoPlay: {
       type: Boolean,
       required: true
     },
     // 自动播放的时间间隔
     duration: {
       type: Number,
       required: true
     }
   },
   setup (props) {
     //   默认显示的照片下标
     const index = ref(1)
     // 定时器:自动播放
     const timer = ref(null)
     const autoPlayFn = () => {
       clearInterval(timer)
       timer.value = setInterval(() => {
         index.value++
         if (index.value >= props.sliders.length) {
           index.value = 0
         }
       }, props.duration * 1000)
     }
     // 监听轮播图数据发生变化的时候
     watch(
       () => props.sliders,
       () => {
         index.value = 0
         // 优化:
         if (props.autoPlay && props.sliders.length > 1) {
           autoPlayFn()
         }
       }
     )
     //   当鼠标进入轮播图时:停止轮播
     const stop = () => {
       if (timer.value) {
         clearInterval(timer.value)
       }
     }
     //   当鼠标离开轮播图时:开始轮播
     const start = () => {
       if (props.autoPlay && props.sliders.length > 1) {
         autoPlayFn()
       }
     }
     // 轮播图左右切换
     const toggle = (i) => {
       index.value += i // i是1/-1
       if (index.value < 0) {
         //   如果是切换到最左边,就显示最后一张
         index.value = props.sliders.length - 1
       } else if (index.value >= props.sliders.length) {
         //   如果是切换到最右边,就显示第一张
         index.value = 0
       }
     }
     // 当组件被销毁的时候清除定时器
     onUnmounted(() => {
       stop()
     })
     return { index, toggle, stop, start }
   }
 }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值