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