为什么要自己写一个轮播组件?
市面上用的最多的轮播组件无疑是 swiper 了,但是它真的太大了,大多数功能都用不到。
使用 [mint-ui] swiper 时我发现,当一个轮播未完成时无法继续滑动,需要等当前的轮播结束后才能继续滑动,使用 vant swiper 时我发现滑动效果不是很流畅。于是决定自己写一个 swiper。
- github地址:yus-swipe
- h5 体验地址:demo
- scale effect 效果(类似于APP):demo
从体验上讲,我实现的这个比其他两者都要好,更接近swiper,喜欢的话点个star,同时也接受批评。
撸起袖子开始写
Props 定义
// 轮播方向
direction: {
type: String,
default: VERTICAL,
validator: value => [VERTICAL, HORIZONTAL].indexOf(value) > -1
},
// 是否无限模式
loop: {
type: Boolean,
default: false
},
// 轮播速度
speed: {
type: Number,
default: 300
},
// 初始索引
activeIndex: {
type: Number,
default: 0
},
// 是否自动轮播
autoplay: {
type: Boolean,
default: false
},
// 轮播间隔
delay: {
type: Number,
default: 4000
},
// 切换效果
effect: {
type: String,
default: 'slide'
}
data 定义
data() {
return {
wrapperEl: null,
containerEl: null,
width: undefined,
height: undefined,
slides: [],
isScrolling: undefined,
length: undefined,
size: undefined,
touches: {
startX: undefined,
startY: undefined,
endX: undefined,
endY: undefined,
diff: undefined,
diffX: undefined,
diddY: undefined,
currentX: undefined,
currentY: undefined,
startTranslate: undefined,
time: undefined,
isMoved: undefined
},
gridIndex: 0,
slidesGrid: [],
translate: 0,
currentIndex: this.activeIndex,
transitionDuration: 0,
rectProp: '',
maxGridIndex: 0,
minGridIndex: 0,
maxTranslate: 0,
minTranslate: 0,
interval: null,
realLength: 0
};
},
Methods 定义
// 初始化方法
function setup () {}
// start handler
function onTouchStart (event) {}
// move handler
function onTouchMove (event) {}
// end handler
function onTouchEnd () {}
// 轮播到第几页
function slideTo(newIndex, speed) {}
// 轮播到下一页
function slideNext() {}
// 轮播到上一页
function slidePrev() {}
// 开启自动轮播
function start () {}
// 关闭自动轮播
function stop () {}
// 设置便宜位置
function setTranslate (newTranslate) {}
// 为 loop 模式创建 dom
function createLoopEl() {}
定义好大概的框架之后,我们就可以一步一步的补充细节了。
过程中的关键点(重要)
loop模式的实现
假设容器宽度为375px, slide length 为 3,loop 模式下 复制节点后的 length 为 5,此时 slideGrid 为 [0, 1, 2, 3, 4]
方法1:当滑动4时,等待动画结束后将位置调整为1,onTouchStart
判断当前的动画是否完成,没有完成的话不允许滑动。这种情况下不能连续滑动,否则容易出现bug,mint-ui 就是类似这样的实现,体验效果不是很好。
方法2:在 onTouchMove 中判断当前位置是否超出限制,如果超出限制,调整位置,这一步比较关键,具体可以看源码。
添加 vetur 代码提示支持
添加完 vetur 后在vscode即可支持 tag 和 attribute 只能提示了。
发布到 NPM
最后一步发布就可以了。
总结
我表达能力太差了,如有错误或想吐槽的地方,尽管侮辱我吧,。接受批评,希望大家点个赞。