之前用jQuery写过轮播组件,用的jquery动画实现的图片滑动效果。这个组件的滑动特效是原生js搭配vue的数据绑定实现的,不依赖其他库,虽然可以再vue.js中引入swiper,但是引入类库的最大的缺点就是冗余代码太多,所以还是自己写一个比较好,简单扼要。(ps:组件的宽高设置还有有点小bug,子组件中需要改为用js动态修改container的宽高,另外可能还有其他地方有不合理之处,欢迎各位批评指正)
github地址:git@github.com:cainiao222/vueslider-components.git
父组件代码:
<template> <p> <slider :img="img" :width="width" :height="height"></slider> </p> </template> <script> // import swiper from 'swiper' import slider from './slider1.vue' export default { data(){ return { img:[{src:require('../assets/slideShow/pic1.jpg'),name:'hehe1'}, {src:require('../assets/slideShow/pic2.jpg'),name:'hehe2'}, {src:require('../assets/slideShow/pic3.jpg'),name:'hehe3'}, {src:require('../assets/slideShow/pic4.jpg'),name:'hehe4'} ], width:460, height:250 } }, components:{ slider:slider } } </script>
子组件代码:
<template> <p class="box"> <p @mouseenter="endInterval" @mouseleave="startInterval" class="container"> <p :style="{width:wrap_width+'px',height:wrap_height+'px',left:offset_left+'px'}" class="slider-wrap"> <p class='img' v-for="item in slider_des"> <img :src="item.src" alt=""> </p> </p> <p class="bottom"> <ul class="pointContainer"> <li @click="changeIndex(index)" :class="{point:true,active:nowIndex===index}" v-for="(point,index) in length"></li> </ul> </p> <p @click="pre" class="click pre"><</p> <p @click="next" class="click next">></p> </p> </p> </template> <script> export default { props:{ img:{ type:Array, default:[] }, width:{ type:Number, default:460 }, height:{ type:Number, default:250 } }, mounted(){ this.startInterval(); }, data(){ console.log(this.width); return{ length:new Array(this.img.length), nowIndex:0, wrap_width:this.width*(this.img.length+2), wrap_height:this.height, offset_left:-this.width, isTransition:true, timer:null, animateFlag:true, timerAuto:null } }, computed:{ slider_des:function () { var arr=[]; var arr1=arr.concat(this.img); arr1.push(this.img[0]); arr1.unshift(this.img[this.img.length-1]); return arr1; } }, methods:{ pre(){ if(this.nowIndex===0){ if(!this.animateFlag){ clearInterval(this.timer); this.animateFlag=true; this.offset_left=-(this.length.length)*this.width; } this.animate(-this.width,0,function (that) { that.offset_left=-(that.length.length)*that.width; }); this.nowIndex=this.img.length-1; return }else{ if(!this.animateFlag){ this.animateFlag=true; clearInterval(this.timer); this.offset_left=-(this.nowIndex*this.width); } this.animate(-(this.nowIndex+1)*this.width,-(this.nowIndex*this.width)); } this.nowIndex-=1; }, startInterval(){ this.timerAuto=setInterval(this.next,2000); }, endInterval(){ // console.log("leave"); clearInterval(this.timerAuto); }, next(){ if(this.nowIndex===this.length.length-1){ if(!this.animateFlag){ this.animateFlag=true; clearInterval(this.timer); this.offset_left=-this.width; } this.animate(-(this.length.length)*this.width,-(this.length.length+1)*this.width,function (that) { that.offset_left=-that.width; }); this.nowIndex=0; return }else{ if(!this.animateFlag){ this.animateFlag=true; clearInterval(this.timer); this.offset_left=-(this.nowIndex+2)*this.width; } this.animate(-(this.nowIndex+1)*this.width,-(this.nowIndex+2)*this.width); this.nowIndex+=1; } }, animate(start,end,fuc){ var distance=end-start; var pre_dis=distance/50; var that=this; this.timer=setInterval(function () { that.animateFlag=false; if(Math.abs(end-that.offset_left)<=Math.abs(pre_dis)){ that.offset_left=end; if(fuc){ fuc(that); } that.animateFlag=true; clearInterval(that.timer); that.timer=null; return } that.offset_left+=pre_dis; },1); }, changeIndex(index){ clearInterval(this.timer); this.animate(-(this.nowIndex+1)*this.width,-(index+1)*this.width); this.nowIndex=index; } } } </script> <style scoped> *{ margin: 0; list-style: none; /*height: 0;*/ } .box{ position: relative; } .container{ width: 460px; height: 250px; margin: 0 auto; border: 1px solid #3bb4f2; overflow: hidden; left: 0; top: 0; position: absolute; } .slider-wrap{ /*width: 2760px;*/ /*height: 250px;*/ position: absolute; /*left: -460px;*/ /*overflow: hidden;*/ top: 0; } .transition{ transition: 0.5s; } .img{ width: 460px; height: 250px; float: left; display: inline; } img{ width: 460px; height: 250px; /*float: left;*/ } .click{ width: 20px; background-color: rgba(255,255,255,.3); color: aliceblue; font-weight: bold; position: absolute; height: 40px; line-height: 40px; margin-top: -20px; top: 50%; cursor: pointer; } .pre{ left: 0; } .next{ right: 0; } .bottom{ position: absolute; bottom: 0; width: 100%; height: 20px; text-align: center; } .pointContainer{ height: 20px; } .point{ display: inline-block; border: 5px solid #eeeeee; border-radius: 5px; line-height: 0; margin-right: 3px; } .active{ border: 5px solid #42b983; } </style>