赞
踩
组件说明:
实现无缝轮播。
效果展示:
无缝轮播效果
实现的功能:
使用div:
<template>
<el-carousel-img>
<div style="background: pink;font-size:3rem;text-align: center">1</div>
<div style="background: yellow;font-size:3rem;text-align: center">2</div>
</el-carousel-img>
</template>
使用图片:
<template> <el-carousel-img> <img :src="carpool" alt=""> <img :src="gold" alt=""> </el-carousel-img> </template> <script> import carpool from '../assets/carpooling.png'; import gold from '../assets/gold-detail.png'; export default { data(){ return{ carpool, gold } } } </script>
属性 | 说明 | 类型 | 默认值 |
---|---|---|---|
height | 轮播图高度,注意,如果设置了指定高度,图片也要设置高度 | String | 200px |
interval | l轮播间隔时间 | Number | 2000ms |
transitionTime | 轮播过度时间,必须小于轮播间隔时间 | Number | 1000ms |
isIndicator | 是否显示指示灯 | Boolean | true |
isHandle | 是否显示左右按钮 | Boolean | true |
autoplay | 是否自动播放 | Boolean | true |
CarouselImg.vue
<template> <div class="carousel-container" :style="{height:height}" @mouseenter.stop="handleMouseEnter" @mouseleave.stop="handleMouseLeave" > <div v-if="handleDisplay"> <button class="carousel-arrow carousel-arrow-left" @click.stop="throttledArrowClick(controlDisabled[0].label)" :disabled="controlDisabled[0].disabled" ><i class="arrow-left"></i></button> <button class="carousel-arrow carousel-arrow-right" @click.stop="throttledArrowClick(controlDisabled[1].label)" :disabled="controlDisabled[1].disabled" ><i class="arrow-right"></i></button> </div> <div ref="list" class="carousel-list" @touchstart="moveStart" @touchmove="moving" @touchend="moveEnd" > <slot class="carousel-pane"></slot> </div> <ul class="carousel-indicator" v-if="isIndicator" ref="indicator"> <li v-for="(item,index) in carouselLength" @click="setCurrentItem(index)" :class="[index == (currentIndex-1)?'is-active-item':'','carousel-indicator-item']"> </li> </ul> </div> </template> <script> export default { name: "ElCarouselImg", data(){ return { currentIndex:1,//当前索引 carouselLength:0,//实际轮播图个数 timer:null,//定时器 handle:false,//是否显示左右点击按钮 //设置点击状态 controlDisabled:[ {label:'leftBtn',disabled:false}, {label:'rightBtn',disabled:false}, {label:'child',disabled:false}, ], isMoving:false, start: { x: 0 }, time:0,//滑动时触摸结束回弹时间。 imgList:null,//轮播图片的父元素 width:window.innerWidth//移动距离 } }, props:{ interval: { type: Number, default: 2000//轮播间隔时间 }, transitionTime:{ type: Number, default: 1000//轮播过度时间 }, isIndicator: { type: Boolean, default: true//是否显示指示灯 }, height: String,//轮播图高度 isHandle:{ type: Boolean, default: true//是否显示左边点击按钮,默认点击图片并且图片大于1张时显示 }, isAutoplay:{ type: Boolean, default: true//是否开启自动轮播 } }, computed: { handleDisplay() { return this.isHandle && this.handle && this.carouselLength>1; }, }, mounted(){ //启动轮播图 this.prepare(); }, created(){ }, methods:{ moveStart(e){ e.stopPropagation(); this.start.x = e.changedTouches[0].pageX; }, moving(e){ e.stopPropagation(); this.pauseTimer(); var distanceX = e.changedTouches[0].pageX - this.start.x; this.imgList.style.transform ='translate3d('+ (-this.currentIndex * this.width + distanceX) +'px,0,0)'; this.imgList.style.transition = 'transform 0s'; this.isMoving = true; }, moveEnd(e){ if(this.isMoving){ e.stopPropagation(); this.time = 300; var distanceX = e.changedTouches[0].pageX - this.start.x; if(distanceX<0){ this.currentIndex++ ; if(this.currentIndex == this.carouselLength+1){ this.criticality(1,undefined,300); }else { this.play(300); } }else{ this.currentIndex-- ; if(this.currentIndex == 0){ this.criticality(this.carouselLength,undefined,300); }else { this.play(300); } }; this.isMoving = false; this.autoPlay(); } }, prepare(){ this.imgList = this.$refs.list; var children = this.imgList.children; this.carouselLength = children.length; if(this.carouselLength>1){ this.width = this.imgList.clientWidth; //首尾各添加一张图片,以便无缝轮播 var firstDom = this.imgList.firstElementChild && this.imgList.firstElementChild.cloneNode(true); var lastDom = this.imgList.lastElementChild && this.imgList.lastElementChild.cloneNode(true); if(this.imgList.firstElementChild){ this.imgList.appendChild(firstDom); this.imgList.insertBefore(lastDom,this.imgList.firstElementChild); this.imgList.style.transform ='translate3d('+ (-this.width) +'px,0,0)'; } if(this.isAutoplay){ this.autoPlay(); } } }, //停止定时器 pauseTimer(){ if(this.timer){ clearTimeout(this.timer); this.timer = null; } }, handleMouseEnter(){ if(this.isHandle){ this.handle = true; this.pauseTimer(); } }, handleMouseLeave(){ if(this.isHandle||this.handle){ this.handle = false; this.autoPlay(); } }, throttledArrowClick(dir){ if(dir == 'leftBtn'){ this.currentIndex -- ; }else { this.currentIndex ++ ; }; if(this.currentIndex == 0){ this.criticality(this.carouselLength,this.controlDisabled[0]); }else if(this.currentIndex == (this.carouselLength+1)){ this.criticality(1,this.controlDisabled[1]); }else { this.play(); } }, //轮播处理逻辑 play(transitionTime){ this.imgList.style.transform ='translate3d('+ (-this.currentIndex * this.width)+'px,0,0)'; if(transitionTime){ this.imgList.style.transition = 'transform '+transitionTime+ 'ms'; }else { this.imgList.style.transition = 'transform '+this.transitionTime+ 'ms'; } }, setCurrentItem(index){ //点击指示灯时停止轮播。 this.pauseTimer(); if(this.controlDisabled[2].disabled){ return; } //点击第一张时 if(index == 0 && this.currentIndex == (this.carouselLength)){ this.currentIndex++; this.criticality(1,this.controlDisabled[2]); }else if(index == (this.carouselLength-1) && this.currentIndex == 1){ this.currentIndex -- ; this.criticality(this.carouselLength,this.controlDisabled[2]); }else { this.currentIndex = index+1; this.play(); } }, criticality(boundary,item,transitionTime){ this.play(transitionTime); this.currentIndex = boundary; setTimeout(()=>{ this.imgList.style.transform ='translate3d('+ (-this.width*boundary)+'px,0,0)'; this.imgList.style.transition = 'transform 0ms'; },transitionTime?transitionTime:this.transitionTime); //点击临界值时将点击状态暂停掉以便偷梁换柱 if(item){ var after = new Date().getTime()+1000+100; if((new Date().getTime())<= after){ item.disabled = true; setTimeout(()=>{ item.disabled = false; },after-new Date().getTime()) } } }, autoPlay(){ this.timer = setInterval(()=>{ this.currentIndex++; if(this.currentIndex == this.carouselLength+1){ clearInterval(this.timer); this.criticality(1); this.autoPlay(); }else { this.play(); } },this.interval); } }, beforeDestroy() { this.pauseTimer(); } } </script> <style> .carousel-container{ position: relative; width:100%; height: 200px; overflow: hidden; } .carousel-indicator{ display: flex; bottom: 10%; position: absolute; z-index: 99; width: 100%; justify-content: center; } .is-active-item{ opacity: 1!important; } .carousel-indicator-item{ margin: 0 5px; background: #fff; width: 30px; height: 3px; list-style: none; border-radius: 20px; opacity: 0.5; } .carousel-list{ display: flex; position: relative; } .arrow-left,.arrow-right{ font-family: element-icons; font-style: normal; } .arrow-right:before { content: "\e6e0" } .carousel-list img{ width: 100%; flex-shrink: 0; } .carousel-list div{ width: 100%; flex-shrink: 0; overflow: hidden; } .arrow-left:before { content: "\e6de" } .carousel-arrow { border: none; outline: 0; padding: 0; margin: 0; height: 36px; width: 36px; cursor: pointer; -webkit-transition: .3s; transition: .3s; border-radius: 50%; background-color: rgba(31, 45, 61, .11); color: #FFF; position: absolute; top: 50%; z-index: 10; -webkit-transform: translateY(-50%); transform: translateY(-50%); text-align: center; font-size: 12px } .carousel-arrow-left{ left: 15px; } .carousel-arrow-right{ right: 15px; } </style>
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。