Vue滑动翻页组件swiper的实现---第二版
优化的点:
1、改变组件结构,滑动组件的宽度由100vw改为自定义
SwiperPage.vue
<template>
<div class="ths_swiper-page">
<t-swiper-wrap>
<t-swiper-item>
<div class="swiper" style="background: #ccc"><p>swiper1</p><p>swiper1</p></div>
</t-swiper-item>
<t-swiper-item>
<div class="swiper" style="background: #eee"><p>swiper2</p></div>
</t-swiper-item>
<t-swiper-item>
<div class="swiper" style="background: #aaa"><p>swiper3</p></div>
</t-swiper-item>
</t-swiper-wrap>
</div>
</template>
<style lang='scss'>
.ths_swiper-page {
.swiper{
display: inline-block;
width: 100vw; /*自定义宽度*/
}
}
</style>
SwiperWrap.vue
<template>
<div class="ths_swiper-wrap">
<slot></slot>
</div>
</template>
<style lang='scss'>
.ths_swiper-wrap {
white-space: nowrap;
display: inline-block;
padding: 40px 0px;
border: 1px solid #cccccc;
font-size: 0;
}
</style>
SwiperItem.vue
<template>
<div class="ths_swiper"
ref="swiper"
@touchstart="touchstart"
@touchmove="touchmove"
@touchend="touchend">
<slot></slot>
</div>
</template>
<style lang='scss'>
.ths_swiper {
position: relative;
display: inline-block;
text-align: center;
font-size: 14px;
transform: translateX(0)
}
</style>
2、滑动时改变的元素属性由left变为transform,便于使用transition来添加动态效果
3、滑动阙值由写死的值变为页面宽度的1/3
mounted () {
this.pageWidth = this.$refs.swiper.clientWidth
this.elementWidth = this.$refs.swiper.parentNode.offsetWidth
this.swiperEles = document.querySelectorAll('.ths_swiper')
},
methods: {
touchstart (e) {
this.originalPos = e.touches[0].pageX
const transform = this.swiperEles[0].style.transform
this.originalLeft = Number(transform ? transform.split('(')[1].split('px')[0] : 0)
},
touchmove (e) {
let moveDistance = e.touches[0].pageX - this.originalPos // >0 右滑,<0 左滑
this.doSlide(moveDistance, false)
},
touchend (e) {
let moveDistance = e.changedTouches[0].pageX - this.originalPos // >0 右滑,<0 左滑
const transform = this.swiperEles[0].style.transform
let currentLeft = Number(transform ? transform.split('(')[1].split('px')[0] : 0)
if ((Math.abs(moveDistance) > this.pageWidth / 3 && ((moveDistance > 0 && currentLeft < 0) || (moveDistance < 0 && Math.abs(currentLeft) < this.elementWidth - this.pageWidth)))) {
// 滑动距离大于阙值,且内容在边界内时,滑动一整页
let distance = moveDistance > 0 ? this.pageWidth : -this.pageWidth
this.doSlide(distance, true)
} else {
// 滑动回原处
this.doSlide(0, true)
}
},
/**
* 滑动方法
* @param {Number} distance 滑动距离
* @param {Boolean} delay 滑动是否有动画效果
*/
doSlide (distance, delay = false) {
this.swiperEles.forEach((element, index) => {
element.style.transform = `translateX(${this.originalLeft + distance}px)`
element.style.transition = delay ? 'transform .3s' : 'initial'
})
}
}
效果:
第一版遗留的问题依然待解决......