花了兩天半共虑,vue原生輪播終于搞完

功能包括:
可以無縫循環(huán)允扇,也可以不無縫循環(huán)
可以配置左右按鈕和下面的小點點按鈕
下面的小點點按鈕可以點擊
支持手指滑動輪播
可以配置自動輪播,
可以配置小圓點的樣式

后續(xù):現(xiàn)在只是開發(fā)缠局,必須會有bug ,以后的日子就要用它來上項目進行完善功能啦考润,里面有使用說明

<template>
  <div class="wrap">
    <!-- 圖片 -->
    <ul class="swiper" ref="swiper" @touchstart='startfn($event)' @touchmove='movefn($event)' @touchend='endfn($event)'>
        <li class="item" :style="{'width':w+'px'}" v-if="options.loop">
          <img :src="swiperimg[swiperimg.length-1].src" ref="img" />
        </li>
        <li class="item" v-for="(item,index) in swiperimg" :style="{'width':w+'px'}" :key="index">
          <img :src="item.src" ref="img" />
        </li>
        <li class="item" :style="{'width':w+'px'}" v-if="options.loop">
          <img :src="swiperimg[0].src" ref="img" />
        </li>
    </ul>
    <!--  左右按鈕-->
    <span class="prevbtn" ref="prevbtn" v-show="options.prevnextbtn"  @click='go($event,-1)'>&lt;</span>
    <span class="nextbtn" ref="nextbtn"  v-show="options.prevnextbtn"   @click="go($event,1)">&gt;</span>
    <div class="dotbtn" ref="dotbtn" v-show="options.dotbtn">
        <span v-for="(item,index) in swiperimg" :key="index"  @click='dotclick(index)'>{{index+1}}</span>
    </div>
  </div>
</template>

<script>
export default {
  data () {
    return {
      x:-document.documentElement.getBoundingClientRect().width,//ul平移的大小
      w:document.documentElement.getBoundingClientRect().width,//獲取屏幕的寬度
      oUl:'',
      aLi:'',
      iNow:1,
      bReady:true, //限制點擊狭园,當(dāng)動畫正在動時,將不能再點擊
      downX:'',
      disX:'',
      timer:'', //自動播放時間id
      aSpan:'',
      speed:0,
      leng:0,
      dotbtnstyle:{}
    }
  },
  mounted(){
    this.oUl=this.$refs.swiper;
    this.aLi=this.oUl.children;
    this.aSpan=this.$refs.dotbtn.children;
    this.leng=this.aLi.length;
    this.speed=this.options.speed || .5;
    this.dotbtnstyle=this.options.dotbtnstyle || {
      default:`width:20px;height: 20px; margin:0 10px;background: red;`,
      cur:`width:20px;height:20px;background:green;margin:0 10px;`
    }
    this.initswiper();
    this.dotsspanstyle();
  },
  props:['options','swiperimg'],
  methods:{
    initswiper(){
      this.oUl.style.width=this.leng*this.w+'px';
      if(this.options.loop){
        this.oUl.style.WebkitTransform='translateX('+this.x+'px)';
      }else{
        this.iNow=0;
        this.x=0;
        this.aSpan[0].style.background='green'
      }
      if(this.options.autoplay){this.autoplayfn()};
    },
    go(e,step){
      if(!this.options.loop){//沒有循環(huán)的時候
        if(!!e.style){//自動播放時沒有currentTarget //有問題糊治,得修改
          if(this.iNow==this.aSpan.length-1){
            this.iNow=-1;
          }
        }
        if(!!e.currentTarget && e.currentTarget.style.opacity=='0.3'){
          return
        }
      }
      if(this.bready==false)return;
      this.bready=false;
      clearInterval(this.timer)
      this.iNow+=step;
      this.panduaniNow()
      this.dongqilai(1)
    },
    startfn(ev){
       if(this.bready==false)return;
       this.bready=false;
       clearInterval(this.timer)
       this.oUl.style.WebkitTransition='none';
       this.downX=ev.targetTouches[0].pageX;
       this.disX=this.downX-this.x;
    },
    movefn(ev){//需要優(yōu)化唱矛,如果用戶上下滑動了 ev.preventDefault();
      ev.preventDefault();
      if(!this.options.loop && (ev.targetTouches[0].pageX-this.disX)>=100){
            this.oUl.style.WebkitTransform='translateX(100px)';
      }else if(!this.options.loop &&  (ev.targetTouches[0].pageX-this.disX)<=(-this.w*(this.leng-1)-100)){
      }else{
          this.oUl.style.WebkitTransform='translateX('+(ev.targetTouches[0].pageX-this.disX)+'px)';
      }

    },
    endfn(ev){
      this.$refs.swiper.removeEventListener('touchmove',this.movefn)
      var upX=ev.changedTouches[0].pageX;
      if(this.downX==upX){ //如果用戶只是點擊了一下
        this.bready=true;
      }
      if(Math.abs(upX-this.downX)>100){
          this.downX>upX ? this.iNow++ : this.iNow--
          if(!this.options.loop){
            this.iNow==-1 ? this.iNow=0 : ''
            this.iNow==this.leng ? this.iNow=this.leng-1 : ''
          }
          this.panduaniNow()
      }
      this.dongqilai(1)
    },
    tend(){
      this.bready=true;
      this.oUl.removeEventListener('transitionend',this.tend,false);
      if(this.options.loop){
        if(this.iNow==this.leng-1){
            this.iNow=1;
        }
        if(this.iNow==0){
            this.iNow=this.leng-2;
        }
        this.dongqilai(0)
      }else{
        this.dongqilai(1)
      }

    },
    dotclick(index){
      if(!this.options.loop){
        if(index==this.iNow){return} //如果當(dāng)前的顯示和點擊的是同一個,則return
      }
      if(this.options.loop){
        if((index+1)==this.iNow){return} //如果當(dāng)前的顯示和點擊的是同一個俊戳,則return
      }
      if(this.bready==false)return;
      this.bready=false;
      clearInterval(this.timer)
      this.options.loop ?  this.iNow=index+1 : this.iNow=index;
      this.dongqilai(1)
    },
    panduaniNow(){
        if(this.iNow==this.leng){this.iNow=this.leng-1;}
        if(this.iNow==-1){this.iNow=0;}
    },
    dongqilai(type){
      // 如果傳0 表示揖赴,要清掉動畫 ,傳1 表示正常動畫
      if(type==0){
        this.oUl.style.WebkitTransition='none';
      }else{
        this.oUl.style.WebkitTransition=this.speed+'s all ease';

        this.oUl.addEventListener('transitionend',this.tend,false);
        this.dotsspancur()
        this.dotsspanstyle()
      }
      this.x=-this.iNow*this.w;
      this.oUl.style.WebkitTransform='translate3d('+this.x+'px,0,0)';
      if(this.options.autoplay){this.autoplayfn()};
    },
    autoplayfn(){
      clearInterval(this.timer)
      this.timer=setInterval(()=>{
        this.go(this.$refs.nextbtn,1) //自動播放時第一個參數(shù)傳nextbtn這個對象
      },this.options.autoplay)
    },
    dotsspancur(){
      if(!this.options.loop){
          //如果輪播不是循環(huán)時抑胎,當(dāng)運動到第一個燥滑,或者第三個,則為透明阿逃,不能點擊
        if(this.iNow==this.aSpan.length-1){
          this.$refs.nextbtn.style.opacity='.3'
          this.$refs.prevbtn.style.opacity='1'
        }else if( this.iNow==0){
          this.$refs.prevbtn.style.opacity='.3'
          this.$refs.nextbtn.style.opacity='1'
        }else{
          this.$refs.nextbtn.style.opacity='1'
          this.$refs.prevbtn.style.opacity='1'
        }
      }
    },
    dotsspanstyle(){
      for(var i=0;i<this.aSpan.length;i++){
          this.aSpan[i].setAttribute('style',this.dotbtnstyle.default)
      }
      var n;
      n= this.options.loop ? this.iNow-1 :this.iNow
      this.aSpan[(n+this.aSpan.length)%this.aSpan.length].setAttribute('style',this.dotbtnstyle.cur)
    }
  }
}
/*
*author:lipanke
*day:2017-12-06
*update :2017-12-13
*使用方法:
1: import swiper from './Swiper'
2:data里的數(shù)據(jù)
swiperOption: { //基本配置
   autoplay: 500,//自動播放時間
   //dotbtn :true, //是否顯示下面的小點點
   prevnextbtn:true, //是否顯示左右的按鈕
   speed:.2,//運動的速度 以s為單位
   loop:true, //是否無縫滾動
   dotbtnstyle:{  //給小圓點配置樣式铭拧,default是默認的樣式,cur是當(dāng)前顯示的樣式
    default:`width:14px;font-size:12px;height:14px;font-size:12px;background:purple;color:yellow;margin:0 5px;`,
    cur:`width:14px;font-size:12px;height:14px;font-size:12px;background:yellow;color:purple;margin:0 5px;`
  }
},
swiperimg:[
  {
    href:'https://www.baidu.com/',
    src:require('../assets/swiper1.jpg')
  },
  {
    href:'https://www.taobao.com/',
    src:require('../assets/swiper2.jpg')
  }

  3:<swiper :options="swiperOption" :swiperimg="swiperimg"></swiper>
  4:在components里注冊
*/
</script>

<style scoped>
.wrap{overflow: hidden;position: relative;}
.swiper{ }
.swiper:after{content: '';display:block; clear: both;}
.item{float: left;}
.swiper a{display: block;}
.swiper img{width: 100%}
.prevbtn,.nextbtn{position: absolute;top:50%;transform: translateY(-50%);font-size: 30px; color: #fff;z-index: 2;}
.prevbtn{left:20px;}
.nextbtn{right:20px;}
.dotbtn {position: absolute;bottom: 14px;  width: 100%; display: flex;align-items: center; justify-content:center;}
.dotbtn span{border-radius: 50%; color: #fff; display: flex;justify-content: center;align-items: center}
</style>

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末恃锉,一起剝皮案震驚了整個濱河市搀菩,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌破托,老刑警劉巖肪跋,帶你破解...
    沈念sama閱讀 211,348評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異土砂,居然都是意外死亡州既,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,122評論 2 385
  • 文/潘曉璐 我一進店門萝映,熙熙樓的掌柜王于貴愁眉苦臉地迎上來吴叶,“玉大人,你說我怎么就攤上這事序臂“雎保” “怎么了?”我有些...
    開封第一講書人閱讀 156,936評論 0 347
  • 文/不壞的土叔 我叫張陵,是天一觀的道長逊彭。 經(jīng)常有香客問我咸灿,道長,這世上最難降的妖魔是什么诫龙? 我笑而不...
    開封第一講書人閱讀 56,427評論 1 283
  • 正文 為了忘掉前任析显,我火速辦了婚禮,結(jié)果婚禮上签赃,老公的妹妹穿的比我還像新娘谷异。我一直安慰自己,他們只是感情好锦聊,可當(dāng)我...
    茶點故事閱讀 65,467評論 6 385
  • 文/花漫 我一把揭開白布歹嘹。 她就那樣靜靜地躺著,像睡著了一般孔庭。 火紅的嫁衣襯著肌膚如雪尺上。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,785評論 1 290
  • 那天圆到,我揣著相機與錄音怎抛,去河邊找鬼。 笑死芽淡,一個胖子當(dāng)著我的面吹牛马绝,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播挣菲,決...
    沈念sama閱讀 38,931評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼富稻,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了白胀?” 一聲冷哼從身側(cè)響起椭赋,我...
    開封第一講書人閱讀 37,696評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎或杠,沒想到半個月后哪怔,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,141評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡向抢,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,483評論 2 327
  • 正文 我和宋清朗相戀三年认境,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片笋额。...
    茶點故事閱讀 38,625評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖篷扩,靈堂內(nèi)的尸體忽然破棺而出兄猩,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 34,291評論 4 329
  • 正文 年R本政府宣布枢冤,位于F島的核電站鸠姨,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏淹真。R本人自食惡果不足惜讶迁,卻給世界環(huán)境...
    茶點故事閱讀 39,892評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望核蘸。 院中可真熱鬧巍糯,春花似錦、人聲如沸客扎。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,741評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽徙鱼。三九已至宅楞,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間袱吆,已是汗流浹背厌衙。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評論 1 265
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留绞绒,地道東北人婶希。 一個月前我還...
    沈念sama閱讀 46,324評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像处铛,于是被迫代替她去往敵國和親饲趋。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,492評論 2 348

推薦閱讀更多精彩內(nèi)容