使用Vue制作图片轮播组件思路详解

之前一直都没有认真的写过一个组件。以前在写业务代码的过程中,都是用的别人封装好的组件,这次尝试着写了一个图片轮播组件,虽然比不上知名的轮播组件,但它的功能基本完整,而且在写这个组件的过程中,学的东西也很多,在这里也给大家分享出来,如有疏漏,欢迎指正!

在制作这个组件之前,笔者google了不少关于轮播的文章,发现实现一个轮播的思路虽然各有不同,但是大的逻辑其实差不多,本文主要依据慕课网上焦点轮播图特效这节课,不过慕课网主要用原生JS写,而笔者则用Vue进行了重构,并且进行了一点修改。完成后的组件效果图如下:

 

一、理清思路,理解需求和原理

1. 要写一个什么样的轮播?

  • 在点击右侧箭头时,图片向左滑动到下一张;点击左侧箭头时,图片向右滑到下一张
  • 点击下面的小圆点,滑到对应的图片,相应小圆点的样式也发生改变
  • 要有过渡效果,要缓缓滑动过去
  • 当鼠标hover到图片上时,轮播暂停,当鼠标leave时,轮播继续
  • 自动播放功能
  • 无限滚动,即在滚动到最后一张时,再点击下一张时会继续向左滑动到第一张,而不是整个拉到第一张,这里有点难

2. 理解无限轮播的原理

我们先看下原理图:

 

图中红线区域即是我们看到的图片,这个轮播 只展示5张图片 ,但是在它的首尾各还有两张图片,在图1前面放置了图5,在图5后面放置了图1,之所以这么做,是为了做无限滚动。 无限滚动的原理在于:当整个图向左侧滚动到右边的图5时,会继续向前走到图1,在完全显示出图1后,会以肉眼看不到的速度向右侧拉回到最左边的图1。 这样,即使再向左侧滑动看到的就是图2了。

如下图:在最后的图1完成过渡完全显示出来后,再将整个列表瞬间向右拉到左侧的图1。另一张边界图图5的滚动也是,不过方向相反。

二、先让图片切换起来

1. 布局和准备

<template>
 <div id="slider">
  <div class="window">  // window上图中红线框
   <ul class="container" :style="containerStyle"> //注意这里的:style //这是图片列表,排成一排
    <li> //列表最前面的辅助图,它和图5一样,用于无限滚动
     <img :src="sliders[sliders.length - 1].img" alt="">
    </li>
    <li v-for="(item, index) in sliders" :key="index"> //通过v-for渲染的需要展示的5张图
     <img :src="item.img" alt="">
    </li>
    <li> //列表最后面的辅助图,它和图1一样,用于无限滚动
     <img :src="sliders[0].img" alt="">
    </li>
   </ul>
   <ul class="direction"> //两侧的箭头
    <li class="left">
     <svg class="icon" width="30px" height="30.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path fill="#ffffff" d="M481.233 904c8.189 0 16.379-3.124 22.628-9.372 12.496-12.497 12.496-32.759 0-45.256L166.488 512l337.373-337.373c12.496-12.497 12.496-32.758 0-45.255-12.498-12.497-32.758-12.497-45.256 0l-360 360c-12.496 12.497-12.496 32.758 0 45.255l360 360c6.249 6.249 14.439 9.373 22.628 9.373z" /></svg>     
    </li>
    <li class="right">
     <svg class="icon" width="30px" height="30.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path fill="#ffffff" d="M557.179 904c-8.189 0-16.379-3.124-22.628-9.372-12.496-12.497-12.496-32.759 0-45.256L871.924 512 534.551 174.627c-12.496-12.497-12.496-32.758 0-45.255 12.498-12.497 32.758-12.497 45.256 0l360 360c12.496 12.497 12.496 32.758 0 45.255l-360 360c-6.249 6.249-14.439 9.373-22.628 9.373z" /></svg>     
    </li>
   </ul>
   <ul class="dots"> //下面的小圆点
    <li v-for="(dot, i) in sliders" :key="i" 
    :class="{dotted: i === (currentIndex-1)}"
    >
    </li>
   </ul>
  </div>
 </div>
</template>
<script>
export default {
 name: 'slider',
 data () {
  return {
   sliders:[
    {
     img:'../../static/images/1.jpg'
    },
    {
     img:'../../static/images/2.jpg'
    },
    {
     img:'../../static/images/3.jpg'
    },
    {
     img:'../../static/images/4.jpg'
    },
    {
     img:'../../static/images/5.jpg'
    }
   ],
   currentIndex:1,
   distance:-600
  }
 },
 computed:{
  containerStyle() { //这里用了计算属性,用transform来移动整个图片列表
   return {
    transform:`translate3d(${this.distance}px, 0, 0)`
   }
  }
 }
}
</script>
      

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/86.html