<template>
<div
:class="{'swiper': true} ">
<div
class="swiper-frame"
@touchstart= "start"
@touchmove= "move"
@touchend= "end"
@mousedown="dragStart"
@mousemove="dragMove"
@mouseup="dragUp"
@mouseleave="dragUp"
:style="{transform: 'translateX('+ (canTranslateX ? (pathDistance+'px') : currentIndex+'00%)'),
transition: 'all' + (canTranslateX ? ' 0s ' : ' 0.65s ') + 'ease 0s'}"
>
<div
v-for="(item, index) in slideShowLists"
class="swiper-frame-item"
:key="index"
:style="{backgroundImage: 'url('+ item.background+')'}"
>
<component :is="item.el"></component>
</div>
</div>
<ul class="swiper-dots">
<li
:class="{'swiper-dots-li': true ,'swiper-dots-li-active': currentIndex === -index }"
v-for="(item, index) in slideShowLists" :key="index"
@click="switchTo(index)"
></li>
</ul>
</div>
</template>
<script lang="js">
export default {
name: 'Swiper',
components: [],
data () {
return {
slideShowLists: this.swiperLists,
startAbscissa: 0,
pathDistance: 0,
endAbscissa: 0,
canTranslateX: false,
currentIndex: 0,
mouse: false,
shake: this.canShake || false
}
},
props: ['swiperLists', 'canShake'],
methods: {
start (event) {
this.startAbscissa = event.touches[0].clientX
},
move (event) {
this.canTranslateX = true
const l = event.changedTouches[0].clientX - this.startAbscissa
if ((this.currentIndex === 0 && l > 0) || (this.swiperLists.length === (-this.currentIndex + 1) && l < 0)) {
this.canTranslateX = this.shake
}
if (this.currentIndex === this.swiperLists.length && l < 0) {
this.canTranslateX = true
this.currentIndex++
} else {
this.pathDistance = l + (event.target.offsetWidth * this.currentIndex)
}
},
end (event) {
this.canTranslateX = false
const l = event.changedTouches[0].clientX - this.startAbscissa
if (l <= -100 && -this.currentIndex !== this.swiperLists.length - 1) {
this.currentIndex--
}
if (l > 100 && this.currentIndex !== 0) {
this.currentIndex++
}
},
switchTo (index) {
this.canTranslateX = false
this.currentIndex = -index
},
dragStart (event) {
event.preventDefault()
if (event) {
this.mouse = true
this.startAbscissa = event.clientX
}
},
dragMove (event) {
event.preventDefault()
if (!this.mouse || !this.shake) {
return
}
const l = event.clientX - this.startAbscissa
this.canTranslateX = true
if (this.mouse) {
this.pathDistance = l + (event.target.offsetWidth * this.currentIndex)
}
},
dragUp (event) {
if (!this.mouse) {
return
}
this.mouse = false
this.canTranslateX = false
const l = event.clientX - this.startAbscissa
if (l <= -100 && this.currentIndex !== -this.swiperLists.length + 1) {
this.currentIndex--
}
if (l > 100 && this.currentIndex !== 0) {
this.currentIndex++
}
}
},
setup (props) {
console.log(props)
}
}
</script>
<style scoped lang="less">
.swiper{
position: relative;
box-sizing: border-box;
overflow: hidden;
height: 100%;
&-bg {
background-size: cover;
background-repeat: no-repeat;
}
&-frame{
display: flex;
flex-direction: row;
//overflow: hidden;
height: 100%;
box-sizing: border-box;
&-item{
width: 100%;
flex-shrink: 0;
height: 100%;
box-sizing: border-box;
background-size: 100% 100%;
background-repeat: no-repeat;
}
}
&-dots {
position: absolute;
bottom: 10%;
display: flex;
align-items: center;
justify-content: center;
list-style: none;
width: 100%;
&-li {
opacity: 1;
border-radius: 50%;
cursor: pointer;
width: 12PX;
height: 12PX;
margin: 0 6PX !important;
background: #ffaf00;
box-sizing: border-box;
&-active {
border: 2px solid #f8f8f8;
}
}
}
}
</style>
vue制作单向轮播组件
最新推荐文章于 2024-06-05 09:34:08 发布