<template>
<div class="home">
<div class="step-2">
<swiper :arrayList="list">
<img slot-scope="props" :src="props.data.src" alt="" />
</swiper>
</div>
</div>
</template>
<script>
import swiper from "./banner"
export default {
name: 'app',
data () {
return {
list: [{
msg:1,
src: require('@/assets/1.jpg')
}, {
msg:2,
src: require('@/assets/2.jpg')
}, {
msg:3,
src: require('@/assets/3.jpg')
}, {
msg:4,
src: require('@/assets/4.jpg')
},
{
msg:5,
src: require('@/assets/4.jpg')
},{
msg:6,
src: require('@/assets/4.jpg')
}
]
}
},
components: {
swiper
}
}
</script>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
img {
display: block;
width: 100%;
}
.step-2 {
position: relative;
}
</style>
<template>
<div class="carousel_cpmponent">
<section class="carousel_content">
<div ref="swiper" class="carousel_swiper" @touchstart="touchstart" @touchmove="touchmove" @touchend="touchend">
<div class="carousel_swiper_item" ref="container" v-for="(item, i) of list" :key="i" :class="{active:index==i}">
{{item.msg}}
</div>
</div>
</section>
<div class="carousel_indicator">
<div v-for="(tag, i) of arrayList.length"
:class="{active:item==i}"
class="carousel-indicator-item" :key="i" />
</div>
</div>
</div>
</template>
<script>
export default {
name: 'swiper',
props: {
autoPlay: {
default: true // 是否支持自动播放
},
duration: {
default: 300 // 滚动一次过度的时间
},
delayed: {
default: 2500 // 多久滚动一次
},
arrayList: Array, // 这个是数据
padding: {
type: Array,
default: function() {
return [10, 20]
}
}
},
data() {
return {
width: 0,
timer:0,
touching: false,
dom: {},
diff: 0, // 目前所在位置
startX: 0, // 手指触到屏幕上的x轴坐标
moveX: 0, // 手指滑动后 手指所在的x轴坐标
index: 0,//轮播图当前index
}
},
computed: {
item(){
return this.list[this.index]&&this.list[this.index].tag;
},
paddingpx() {
return this.padding[0] + this.padding[1]
},
translate() {
return -this.index*(this.width + this.paddingpx)
},
list() {
this.arrayList.map((item,index)=>{return item.tag=index});
return [...this.arrayList.slice(-2), ...this.arrayList, ...this.arrayList.slice(0, 2)]
}
},
created() {
this.index=2;
},
mounted() {
setTimeout(() => {
this.starDom();
this.Transition(0);
this.Translate(this.translate);
this.autoPlay&&this.AutoPlay();
}, 50);
this.$refs.swiper.addEventListener("transitionend",()=>{
console.log("结束");
this.touching=false;
if(this.index-1==this.arrayList.length){
this.index=1;
this.Transition(0);
this.Translate(this.translate);
}
if(this.index==0){
this.index=this.arrayList.length;
this.Transition(0);
this.Translate(this.translate);
}
})
},
methods: {
starDom() { // 初始化数据 以及获取必要的数据
this.width = document.documentElement.clientWidth * 0.8;
this.$refs.container.forEach(item => {
item.style.width = `${this.width}px`;
item.style.margin = `0px ${this.padding[1]}px 0px ${this.padding[0]}px`
})
this.dom = this.$refs.swiper.style;
},
touchstart(e) {
if(this.touching){
return false;
}
this.startX = e.changedTouches[0].clientX;
this.pauseAutoPlay();
},
touchmove(e) {
if(this.touching){
return false;
}
this.moveX = e.changedTouches[0].clientX;
this.diff = this.moveX - this.startX;
this.Transition(0);
this.Translate(this.translate + this.diff);
this.pauseAutoPlay();
},
touchend() {
this.touching=true;
if(this.diff > 30) { //右滑
this.Prev();
} else if(this.diff < -30) { //左滑
this.Next();
} else {
this.Transition(this.duration);
this.Translate(this.translate);
}
this.autoPlay&&this.AutoPlay();
},
Transition(time) {
this.dom.transition = time + 'ms';
this.dom.webkitTransition = time + 'ms';
},
Translate(num) {
this.dom.transform = `translate3d(${num}px, 0, 0)`;
this.dom.transform = `webkikTranslate3d(${num}px, 0, 0)`;
},
Prev(){
this.index--;
this.Transition(this.duration);
this.Translate(this.translate);
},
Next(){
this.index++;
this.Transition(this.duration);
this.Translate(this.translate);
},
AutoPlay(){
this.timer=setInterval(()=>{
this.Next();
},this.delayed)
},
pauseAutoPlay(){
clearInterval(this.timer);
}
}
}
</script>
<style scoped="scoped" lang="less">
.carousel_cpmponent {
width: 100%;
height: 100%;
.carousel_content {
position: relative;
z-index: 1;
width: 100%;
height: 100%;
overflow: hidden;
.carousel_swiper {
width: 100%;
height: 100%;
display: -webkit-box;
transition-duration: 0s linear;
.carousel_swiper_item {
width: 100%;
height: 100px;
line-height: 100px;
text-align: center;
font-size: 24px;
background: green;
&:nth-child(2n){
background: gold;
}
}
}
}
.carousel_indicator {
position: absolute;
bottom: 8px;
width: 100%;
height: 10px;
text-align: center;
background: 0 0;
z-index: 1;
display: flex;
justify-content: center;
.carousel-indicator-item {
width: 8px;
height: 8px;
margin: 1px 7px;
cursor: pointer;
border-radius: 100%;
background: white;
&.active{
background: red;
}
}
}
}
</style>
Swiper
<template>
<div class="home">
<swiper :data="list" :padding="30" :margin="5">
<img class="step-1" slot-scope="props" :src="props.data.src" alt="" />
</swiper>
<div class="hr">-----分割线-----</div>
<div class="step-2" style="display: none;">
<swiper :data="list">
<img slot-scope="props" :src="props.data.src" alt="" />
</swiper>
</div>
<div class="hr">-----分割线-----</div>
</div>
</template>
<script>
import swiper from "./swiper"
export default {
name: 'app',
data () {
return {
list: [{
src: require('@/assets/1.jpg')
}, {
src: require('@/assets/2.jpg')
}, {
src: require('@/assets/3.jpg')
}, {
src: require('@/assets/4.jpg')
}]
}
},
components: {
swiper
}
}
</script>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
img {
display: block;
width: 100%;
}
.step-1 {
border-radius: 10px;
}
.hr {
height: 40px;
line-height: 40px;
font-size: 14px;
text-align: center;
}
.step-2 {
position: relative;
}
.step-2 .carousel_show_bgcolor {
background-color: rgb(133, 224, 103);
}
</style>
<template>
<div class="carousel_cpmponent"
@touchmove="preventDefault">
<section class="carousel_content">
<div ref="swiper"
class="carousel_swiper"
@touchstart="touchstart"
@touchmove="touchmove"
@touchend="touchend">
<div class="carousel_swiper_item"
ref="container"
v-for="(item, i) of list" :key="i"
:index="i"
:style="{padding: `0 ${margin / 2}px`}">
<slot :data="item" :index="i" />
</div>
</div>
</section>
<div v-if="!crevice"
class="carousel_indicator">
<div v-for="(tag, i) of list.length - 2 * infinite"
:class="{ carousel_show_bgcolor: index - 1 + !infinite === i }"
class="carousel-indicator-item" :key="i" />
</div>
</div>
</template>
<script>
export default {
name: 'swiper',
props: {
autoPlay: {
default: true // 是否支持自动播放
},
duration: {
default: 500 // 滚动一次需要的时间
},
delayed: {
default: 250000 // 多久滚动一次
},
data: Array, // 这个是数据
infinite: {
default: true // 是否可以无限轮播
},
padding: {
default: 0 // 每一个轮播大小控制 = 页面整体宽度 - 此项设置
},
margin: {
default: 0 // 每一个轮播和另一个轮播之间的距离
}
},
data() {
return {
width: 0,
auto: true,
slideing: true,
timer1: '',
dom: {},
position: 0, // 目前所在位置
startX: 0, // 手指触到屏幕上的x轴坐标
moveX: 0, // 手指滑动后 手指所在的x轴坐标
index: 0
}
},
computed: {
crevice() {
if(this.data.length < 3) {
return false
}
return !!this.margin
},
list() {
return this.infinite ? [...this.data.slice(-1), ...this.data, ...this.data.slice(0, 1)] :
this.data
}
},
created() {
this.index = +this.infinite
},
mounted() {
setTimeout(() => {
this.starDom()
this.dom.webkitTransition = `translate3d(${this.infinite ? this.width * (-this.crevice - 1) + this.crevice * this.padding / 2 : 0}px, 0px, 0px)`
this.dom.transform = `translate3d(${this.infinite ? this.width * (-this.crevice - 1) + this.crevice * this.padding / 2 : 0}px, 0px, 0px)`
this.autoPlay && this.infinite && this.setTime()
}, 50)
},
methods: {
starDom() { // 初始化数据 以及获取必要的数据
this.width = document.documentElement.clientWidth - this.crevice * this.padding
this.$refs.container.forEach(item => {
item.style.width = `${this.width}px`
})
this.dom = this.$refs.swiper.style
},
touchstart(e) {
if(this.slideing) {
this.clearTimeOut()
this.dom.transition = '0s'
this.dom.webkitTransition = '0s'
this.position = this.getTransform()
this.startX = e.touches[e.touches.length - 1].clientX
}
},
touchmove(e) {
if(this.slideing && this.startX !== -1) {
this.clearTimeOut()
let moveX = e.touches[e.touches.length - 1].clientX - this.startX
if(this.isTouchmove(moveX)) {
this.moveX = moveX
this.setTranslate(this.moveX + this.position)
}
}
},
touchend() {
this.clearTimeOut()
this.setTranslate(this.moveX + this.position)
if(this.moveX > 0 && this.moveX / this.width > 0.2) {
this.index--
}
if(this.moveX < 0 && this.moveX / -this.width > 0.2) {
this.index++
}
this.move('touch')
},
isTouchmove(moveX) {
return this.infinite ? true : (moveX + this.position <= 0 && moveX + this.position > (this.list.length - 1) * -this.width)
},
setTranslate(d) {
if('transform' in document.documentElement.style) {
this.transform(d)
} else {
this.webkitTransform(d)
}
},
transform(d) {
this.dom.transform = `translate3d(${d + this.crevice * this.padding / 2}px, 0, 0)`
this.dom.transform = `webkikTranslate3d(${d + this.crevice * this.padding / 2}px, 0, 0)`
},
webkitTransform(d) {
this.dom.webkitTransform = `translate3d(${d + this.crevice * this.padding / 2}px, 0, 0)`
this.dom.webkitTransform = `webkikTranslate3d(${d + this.crevice * this.padding / 2}px, 0, 0)`
},
getTransform() { // 获取当前轮播的偏移量
if('transform' in document.documentElement.style) {
let position = this.dom.transform
position = position.substring(12)
position = position.match(/(\S*)px/)[1]
return Number(position)
} else {
return this.index * -1 * this.width + this.crevice * this.padding / 2
}
},
preventDefault(e) {
e.preventDefault()
},
move(type) {
this.slideing = false
this.dom.transition = type === 'touch' ? '250ms' : this.duration + 'ms'
this.dom.webkitTransition = type === 'touch' ? '250ms' : this.duration + 'ms'
this.setTranslate(this.index * -1 * this.width)
this.moveX = 0
this.startX = -1 // 保证下次重新赋值
this.autoPlay && this.infinite && this.setTime()
let timeDuration = type === 'touch' ? '250' : this.duration
this.infinite && setTimeout(() => {
this.dom.transition = '0s'
this.dom.webkitTransition = '0s'
if(this.index === this.list.length - this.crevice - 1) {
this.index = this.crevice + 1
this.setTranslate(this.index * -1 * this.width)
}
if(this.index === +this.crevice) {
this.index = this.list.length - this.crevice - 2
this.setTranslate(this.index * -1 * this.width)
}
this.auto = true
this.slideing = true
}, timeDuration)
if(!this.infinite) {
this.auto = true
this.slideing = true
}
},
setTime() { // 设置轮询定时器
this.timer1 = window.setTimeout(() => {
if(this.auto) {
this.index++
this.move()
} else {
window.clearTimeout(this.timer1)
}
}, this.delayed)
},
clearTimeOut() { // 取消轮询定时器
this.auto = false
window.clearTimeout(this.timer1)
}
},
activated() {
this.autoPlay && this.infinite && this.setTime()
},
deactivated() {
window.clearTimeout(this.timer1)
},
beforeDestroy() {
window.clearTimeout(this.timer1)
}
}
</script>
<style scoped="scoped" lang="less">
.carousel_cpmponent {
width: 100%;
height: 100%;
.carousel_content {
position: relative;
z-index: 1;
width: 100%;
height: 100%;
overflow: hidden;
.carousel_swiper {
width: 100%;
height: 100%;
display: -webkit-box;
transition-duration: 0s linear;
.carousel_swiper_item {
width: 100%;
height: 100%;
}
}
}
.carousel_indicator {
position: absolute;
bottom: 8px;
width: 100%;
text-align: center;
background: 0 0;
z-index: 1;
.carousel-indicator-item {
display: inline-block;
width: 8px;
height: 8px;
margin: 1px 7px;
cursor: pointer;
border-radius: 100%;
background:
}
}
}
</style>