图片轮播是种很常见的场景和功能,一般移动网站首页的轮播 banner
,商品详情页的商品图片等位置都会用到此功能
像这种常用的场景功能肯定是有人早就写好插件了的,所以遇到这种场景,一般都遵循以下三步:
打开冰箱启动 Github- 搜索
swiper
、slider
、Album
等关键字 - 找到想要的库,
npm install
之
这种做法没毛病,有现成的轮子可用当然拿来主义,因为项目用的是 vue
,所以我在网上找了一圈 基于 vue
的轮播组件库,找到了两个比较满意的库:vue-awesome-swiper、vue-swipe
比较知名的轮播框架,一般都会优先使用这个库,功能丰富,适用于各种轮播场景,什么 左右按钮,动态指示点、进度条指示器、垂直切换、一次性显示多个 slides
……功能简直不要太完善
but
我只是想用其中一小部分基本功能而已,如此多的功能于我而言不仅是看文档费劲,更关键的是会在项目中引入太多的冗余代码,好不容易通过各种手段将代码体积降下来,结果就因为引入了一个包一下回到解放前,要不得要不得
饿了么前端团队出品的一个库,比较精简,代码量也很少,但又过于精简了,例如不支持无限轮播,不支持自定义 swiperItem
,而且总感觉有些生硬的感觉
至于其他本人能够搜索到的库,都没什么名气或者下载量太小,不敢轻易在生产环境引入,于是就萌生了自己造个轮子来搞定这件事,这样组价库的功能和代码体积自己都能控制,就算有什么 bug
也能很快自行修正
先看下最终实现效果:
或者你想自己体验一下,这里也有个写好的 Demo
我已经将此功能打包成了一个
npm package
,可直接下载安装使用,包括样式在内的代码体积压缩后不到18KB
,Gzipped之后不到7KB
,源码 已上传
滑动形式
为了描述方便,先定义一下名词,将每一个滑动小块称为 swiperItem
,将容纳所有滑动小块的容器称为 swiper
:
目前大多数的滑动组件库,都是通过两种方式实现组件的滑动的
第一种,同一时间只渲染三个 swiperItem
,每次滑动到下一个 swiperItem
之后,立即更新这三个 swiperItem
这种做法的优点是,无论有多少个 swiperItem
都不会影响到浏览器的渲染性能,因为无论多少个,每次都只渲染其中的三个,缺点在于如果 swiperItem
的数量本来就少于三个,就需要额外的处理了,而且因为每次最多只能滑动一个 swiperItem
的距离,使用起来不是那么顺滑,vue-swipe采用的是这种
第二种,一次性渲染所有的 swiperItem
,并且有时候为了更顺滑的体验,还会在原 swiperItem
的首尾,再各添加一个 swiperItem
例如,原 swiperItem
的数据为 1, 2, 3, 4, 5
,处理之后变成 5, 1, 2, 3, 4, 5, 1
,vue-awesome-swiper采用的是这种
优点在于使用起来更顺滑,缺点是如果数据量很多,比如有几百几千个的数据量,会影响到浏览器的渲染性能,但一般情况下也不会有那么大的数据量,几十个都已经很少了
综合考虑之下,本人决定采用第二种
数据处理
本组件库提供了两种传入 swiperItem
数据的方式
- 第一种是直接通过
props
传入一个图片的数组
一般来说,轮播组件主要元素都只是一张展示用的图片,所以直接通过 props
传入图片数组的方式基本上可以满足大部分需求
<swiper :urlList="urlList" />
对于这种情况下的首尾追加操作就比较简单,其实就是操作一个数组:
this.currentList = this.urlList.length > 1
? this.urlList.slice(-1).concat(this.urlLis