使用Vue怎么制作一個(gè)圖片輪播組件-創(chuàng)新互聯(lián)

使用Vue怎么制作一個(gè)圖片輪播組件?針對(duì)這個(gè)問題,這篇文章詳細(xì)介紹了相對(duì)應(yīng)的分析和解答,希望可以幫助更多想解決這個(gè)問題的小伙伴找到更簡(jiǎn)單易行的方法。

創(chuàng)新互聯(lián)主要從事成都做網(wǎng)站、網(wǎng)站設(shè)計(jì)、網(wǎng)頁設(shè)計(jì)、企業(yè)做網(wǎng)站、公司建網(wǎng)站等業(yè)務(wù)。立足成都服務(wù)武寧,十余年網(wǎng)站建設(shè)經(jīng)驗(yàn),價(jià)格優(yōu)惠、服務(wù)專業(yè),歡迎來電咨詢建站服務(wù):028-86922220

一、理清思路,理解需求和原理

1. 要寫一個(gè)什么樣的輪播?

  • 在點(diǎn)擊右側(cè)箭頭時(shí),圖片向左滑動(dòng)到下一張;點(diǎn)擊左側(cè)箭頭時(shí),圖片向右滑到下一張

  • 點(diǎn)擊下面的小圓點(diǎn),滑到對(duì)應(yīng)的圖片,相應(yīng)小圓點(diǎn)的樣式也發(fā)生改變

  • 要有過渡效果,要緩緩滑動(dòng)過去

  • 當(dāng)鼠標(biāo)hover到圖片上時(shí),輪播暫停,當(dāng)鼠標(biāo)leave時(shí),輪播繼續(xù)

  • 自動(dòng)播放功能

  • 無限滾動(dòng),即在滾動(dòng)到最后一張時(shí),再點(diǎn)擊下一張時(shí)會(huì)繼續(xù)向左滑動(dòng)到第一張,而不是整個(gè)拉到第一張,這里有點(diǎn)難

2. 理解無限輪播的原理

我們先看下原理圖:

使用Vue怎么制作一個(gè)圖片輪播組件 

圖中紅線區(qū)域即是我們看到的圖片,這個(gè)輪播 只展示5張圖片 ,但是在它的首尾各還有兩張圖片,在圖1前面放置了圖5,在圖5后面放置了圖1,之所以這么做,是為了做無限滾動(dòng)。 無限滾動(dòng)的原理在于:當(dāng)整個(gè)圖向左側(cè)滾動(dòng)到右邊的圖5時(shí),會(huì)繼續(xù)向前走到圖1,在完全顯示出圖1后,會(huì)以肉眼看不到的速度向右側(cè)拉回到最左邊的圖1。 這樣,即使再向左側(cè)滑動(dòng)看到的就是圖2了。

如下圖:在最后的圖1完成過渡完全顯示出來后,再將整個(gè)列表瞬間向右拉到左側(cè)的圖1。另一張邊界圖圖5的滾動(dòng)也是,不過方向相反。

使用Vue怎么制作一個(gè)圖片輪播組件

使用Vue怎么制作一個(gè)圖片輪播組件

二、先讓圖片切換起來

1. 布局和準(zhǔn)備

<template>
 <div id="slider">
  <div class="window">  // window上圖中紅線框
   <ul class="container" :> //注意這里的:style //這是圖片列表,排成一排
    <li> //列表最前面的輔助圖,它和圖5一樣,用于無限滾動(dòng)
     <img :src="sliders[sliders.length - 1].img" >
    </li>
    <li v-for="(item, index) in sliders" :key="index"> //通過v-for渲染的需要展示的5張圖
     <img :src="item.img" >
    </li>
    <li> //列表最后面的輔助圖,它和圖1一樣,用于無限滾動(dòng)
     <img :src="sliders[0].img" >
    </li>
   </ul>
   <ul class="direction"> //兩側(cè)的箭頭
    <li class="left">
     <svg class="icon" width="30px" height="30.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path fill="#ffffff" d="M481.233 904c8.189 0 16.379-3.124 22.628-9.372 12.496-12.497 12.496-32.759 0-45.256L166.488 512l337.373-337.373c12.496-12.497 12.496-32.758 0-45.255-12.498-12.497-32.758-12.497-45.256 0l-360 360c-12.496 12.497-12.496 32.758 0 45.255l360 360c6.249 6.249 14.439 9.373 22.628 9.373z" /></svg>     
    </li>
    <li class="right">
     <svg class="icon" width="30px" height="30.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path fill="#ffffff" d="M557.179 904c-8.189 0-16.379-3.124-22.628-9.372-12.496-12.497-12.496-32.759 0-45.256L871.924 512 534.551 174.627c-12.496-12.497-12.496-32.758 0-45.255 12.498-12.497 32.758-12.497 45.256 0l360 360c12.496 12.497 12.496 32.758 0 45.255l-360 360c-6.249 6.249-14.439 9.373-22.628 9.373z" /></svg>     
    </li>
   </ul>
   <ul class="dots"> //下面的小圓點(diǎn)
    <li v-for="(dot, i) in sliders" :key="i" 
    :class="{dotted: i === (currentIndex-1)}"
    >
    </li>
   </ul>
  </div>
 </div>
</template>
<script>
export default {
 name: 'slider',
 data () {
  return {
   sliders:[
    {
     img:'../../static/images/1.jpg'
    },
    {
     img:'../../static/images/2.jpg'
    },
    {
     img:'../../static/images/3.jpg'
    },
    {
     img:'../../static/images/4.jpg'
    },
    {
     img:'../../static/images/5.jpg'
    }
   ],
   currentIndex:1,
   distance:-600
  }
 },
 computed:{
  containerStyle() { //這里用了計(jì)算屬性,用transform來移動(dòng)整個(gè)圖片列表
   return {
    transform:`translate3d(${this.distance}px, 0, 0)`
   }
  }
 }
}
</script>

好了,布局大概就是這樣,效果圖如下:

使用Vue怎么制作一個(gè)圖片輪播組件 

上面的代碼已經(jīng)做了注釋,有幾個(gè)點(diǎn)在這里再提一下:

  • window是紅線框, 寬度為600px ,它不會(huì)動(dòng),移動(dòng)的是包裹著圖片的container,它的移動(dòng)方式用 : ,這是一個(gè)計(jì)算屬性,用 transform:translate3d(${this.distance, 0, 0}) 來控制左右移動(dòng)

  • data里的 distance 和 currentIndex 是關(guān)鍵, distance 控制著移動(dòng)的距離,默認(rèn)是-600,顯示7張圖片中的第二張,也就是圖1。 currentIndex 是window顯示的圖片的索引,這里默認(rèn)是1,也是7張圖片中第2張。

  • 需要展示的只有5張圖片,但是在圖1前了一張圖5、在圖5后面放了一張圖1來做無限滾動(dòng),原理前面說過了

  • 當(dāng)點(diǎn)擊右側(cè)的箭頭,container向左移動(dòng), distance 會(huì)越來越小;當(dāng)點(diǎn)擊左側(cè)的箭頭,container向右移動(dòng), distance 會(huì)越來越大,方向不要弄錯(cuò)

2. 圖片切換

我們?cè)谧髠?cè)和右側(cè)的箭頭上添加點(diǎn)擊事件:

<ul class="direction">
    <li class="left" @click="move(600, 1)">
     <svg class="icon" width="30px" height="30.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path fill="#ffffff" d="M481.233 904c8.189 0 16.379-3.124 22.628-9.372 12.496-12.497 12.496-32.759 0-45.256L166.488 512l337.373-337.373c12.496-12.497 12.496-32.758 0-45.255-12.498-12.497-32.758-12.497-45.256 0l-360 360c-12.496 12.497-12.496 32.758 0 45.255l360 360c6.249 6.249 14.439 9.373 22.628 9.373z" /></svg>     
    </li>
    <li class="right" @click="move(600, -1)">
     <svg class="icon" width="30px" height="30.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path fill="#ffffff" d="M557.179 904c-8.189 0-16.379-3.124-22.628-9.372-12.496-12.497-12.496-32.759 0-45.256L871.924 512 534.551 174.627c-12.496-12.497-12.496-32.758 0-45.255 12.498-12.497 32.758-12.497 45.256 0l360 360c12.496 12.497 12.496 32.758 0 45.255l-360 360c-6.249 6.249-14.439 9.373-22.628 9.373z" /></svg>     
    </li>
   </ul>
   ......
   methods:{
      move(offset, direction) {
        this.distance += this.distance * direction
        if (this.distance < -3000) this.distance = -600
        if (this.distance > -600) this.distance = -3000
      }
   }

解釋下上面的代碼:點(diǎn)擊左側(cè)或者右側(cè)的箭頭,調(diào)用move函數(shù),move接收偏移量offset和方向direction兩個(gè)參數(shù)。direction只傳兩個(gè)值,1表示container向右移動(dòng),-1表示container向左移動(dòng);偏移量是600,也就是一張圖片的寬度。如果移動(dòng)到7張圖片的最后一張,就把container拉到7張圖片里的第二張;如果移動(dòng)到7張圖片里第一張,就把container拉到7張圖片里的第5張。

效果:

使用Vue怎么制作一個(gè)圖片輪播組件 

可以看到,圖片切換效果已經(jīng)出來了,但是下面的小圓點(diǎn)沒有跟著變換。接下來我們把這個(gè)效果加上。從上面的html代碼可以看到, :class="{dotted: i === (currentIndex - 1)}" ,小圓點(diǎn)的切換效果和data里的currentIndex值相關(guān),我們只要隨著圖片切換變動(dòng)currentIndex值就可以了。

修改move方法里的代碼:

......

move(offset, direction) {
  direction === -1 ? this.currentIndex++ : this.currentIndex--
  if (this.currentIndex > 5) this.currentIndex = 1
  if (this.currentIndex < 1) this.currentIndex = 5
  this.distance = this.distance + offset * direction
  if (this.distance < -3000) this.distance = -600
  if (this.distance > -600) this.distance = -3000
  }

上面的添加的三行代碼很好理解,如果是點(diǎn)擊右側(cè)箭頭,container就是向左移動(dòng), this.currentIndex 就是減1,反之就是加1。

效果:

使用Vue怎么制作一個(gè)圖片輪播組件 

可以看到,小圓點(diǎn)的切換效果已經(jīng)出來了。

三、過渡動(dòng)畫

上面的代碼已經(jīng)實(shí)現(xiàn)了切換,但是沒有動(dòng)畫效果,顯的非常生硬,接下來就是給每個(gè)圖片的切換過程添加過渡效果。

這個(gè)輪播組件筆者并沒有使用Vue自帶的class鉤子,也沒有直接使用css的transition屬性,而是用慕課網(wǎng)原作者講的setTimeout方法加遞歸來實(shí)現(xiàn)。

其實(shí)我也試過使用Vue的鉤子,但是總有一些小問題解決不掉;比如下面找到的這個(gè)例子:例子

這個(gè)例子在過渡的邊界上有一些問題,我也遇到了,而且還是時(shí)有時(shí)無。而如果使用css的transition過渡方法,在處理邊界的無限滾動(dòng)上總會(huì)在chrome瀏覽器上有一下閃動(dòng),即使添加了 -webkit-transform-style:preserve-3d; 和 -webkit-backface-visibility:hidden 也還是沒用,而且要配合transition的 transitionend 事件對(duì)于IE瀏覽器的支持也不怎么好。

如果大家有看到更好的辦法,請(qǐng)?jiān)谠u(píng)論中留言哦~

下面我們來寫這個(gè)過渡效果,主要是改寫:

methods:{
  move(offset, direction) {
    direction === -1 ? this.currentIndex++ : this.currentIndex--
    if (this.currentIndex > 5) this.currentIndex = 1
    if (this.currentIndex < 1) this.currentIndex = 5

    const destination = this.distance + offset * direction
    this.animate(destination, direction)
  },
  animate(des, direc) {
    if ((direc === -1 && des < this.distance) || (direc === 1 && des > this.distance)) {
      this.distance += 30 * direc    
      window.setTimeout(() => {
        this.animate(des, direc)
      }, 20)
    } else {
      this.distance = des
      if (des < -3000) this.distance = -600
      if (des > -600) this.distance = -3000
   }
  }
}

上面的代碼是這個(gè)輪播我覺得最麻煩、也是最難理解的地方。

來理解一下:首先,我們對(duì)于move方法進(jìn)行了改寫,因?yàn)橐稽c(diǎn)點(diǎn)的移動(dòng),所以要先算出要移動(dòng)到的目標(biāo)距離。然后,我們寫一個(gè)animate函數(shù)來實(shí)現(xiàn)這個(gè)過渡。這個(gè)animate函數(shù)接收兩個(gè)參數(shù),一個(gè)是要移動(dòng)到的距離,另一個(gè)是方向。 如果我們點(diǎn)擊了右側(cè)的箭頭,container要向左側(cè)移動(dòng),要是沒有移動(dòng)到目標(biāo)距離,就在 this.distance 減去一定的距離,如果減去后還是沒有到達(dá),在20毫米以后再調(diào)用這個(gè) this.animate ,如此不斷移動(dòng),就形成了過渡效果。而如果移動(dòng)到了目標(biāo)距離,那就將目標(biāo)距離賦值給 this.distance ,然后再進(jìn)行邊界和無限滾動(dòng)的判斷。

當(dāng)然,使用 window.setInterval() 也可以實(shí)現(xiàn)這個(gè)效果,而且會(huì)稍微好理解一點(diǎn),因?yàn)闆]有用到遞歸:

methods:{
  move(offset, direction) {
    direction === -1 ? this.currentIndex++ : this.currentIndex--
    if (this.currentIndex > 5) this.currentIndex = 1
    if (this.currentIndex < 1) this.currentIndex = 5

    const destination = this.distance + offset * direction
    this.animate(destination, direction)
  },
  animate(des, direc) {
    const temp = window.setInterval(() => {
      if ((direc === -1 && des < this.distance) || (direc === 1 && des > this.distance)) {
        this.distance += 30 * direc
      } else {
        window.clearInterval(temp)
        this.distance = des
        if (des < -3000) this.distance = -600
        if (des > -600) this.distance = -3000
      }
    }, 20)
  } 
}

實(shí)現(xiàn)出來的效果如下:

使用Vue怎么制作一個(gè)圖片輪播組件 

四、簡(jiǎn)單節(jié)流一下

寫到這里,效果是出來了,但是會(huì)有一點(diǎn)問題,如果多次快速點(diǎn)擊,就會(huì)有可能出現(xiàn)下面這種情況:

使用Vue怎么制作一個(gè)圖片輪播組件 

出現(xiàn)這種情況的原因很簡(jiǎn)單,因?yàn)槭鞘褂枚〞r(shí)器過渡,所以連續(xù)快速點(diǎn)擊就會(huì)出現(xiàn)錯(cuò)亂,簡(jiǎn)單節(jié)流一下就好了: 在過渡完成之前點(diǎn)擊箭頭無效,其實(shí)就是設(shè)了一個(gè)閘,第一次點(diǎn)擊把閘打開,在閘再次打開之前,讓一部分代碼無法執(zhí)行,然后再在恰當(dāng)?shù)臅r(shí)機(jī)把閘打開。

我們把這個(gè)閘設(shè)在move函數(shù)里:

move(offset, direction) {
  if (!this.transitionEnd) return //這里是閘
  this.transitionEnd = false    //開閘以后再把閘關(guān)上
  direction === -1 ? this.currentIndex++ : this.currentIndex--
  if (this.currentIndex > 5) this.currentIndex = 1
  if (this.currentIndex < 1) this.currentIndex = 5

  const destination = this.distance + offset * direction
  this.animate(destination, direction)
}

this.transitionEnd 是這個(gè)閘的鑰匙,我們把它放到data里:

this.transitionEnd: true

這個(gè)閘一開始默認(rèn)的狀態(tài)是開著的,第一次點(diǎn)擊以后,這個(gè)閘就關(guān)上了, this.tranisitonEnd = false ,在再次打開之前,后面的代碼都執(zhí)行不了。接下來就是在恰當(dāng)?shù)臅r(shí)機(jī)把這個(gè)閘打開,而這個(gè)恰當(dāng)?shù)臅r(shí)機(jī)就是過渡完成時(shí),也就是在 animate函數(shù) 里:

animate(des, direc) {
  if (this.temp) { 
    window.clearInterval(this.temp)
    this.temp = null 
  }
  this.temp = window.setInterval(() => {
    if ((direc === -1 && des < this.distance) || (direc === 1 && des > this.distance)) {
     this.distance += 30 * direc 
    } else {
     this.transitionEnd = true   //閘再次打開
     window.clearInterval(this.temp)
     this.distance = des
     if (des < -3000) this.distance = -600
     if (des > -600) this.distance = -3000
    }
  }, 20)
}

這下快速點(diǎn)擊就沒有之前的那個(gè)問題了:

使用Vue怎么制作一個(gè)圖片輪播組件 

五、點(diǎn)擊小圓點(diǎn)實(shí)現(xiàn)圖片過渡切換

到目前為止的代碼:

<template>
 <div id="slider">
  <div class="window">
   <ul class="container" :>
    <li>
     <img :src="sliders[sliders.length - 1].img" >
    </li>
    <li v-for="(item, index) in sliders" :key="index">
     <img :src="item.img" >
    </li>
    <li>
     <img :src="sliders[0].img" >
    </li>
   </ul>
   <ul class="direction">
    <li class="left" @click="move(600, 1)">
     <svg class="icon" width="30px" height="30.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path fill="#ffffff" d="M481.233 904c8.189 0 16.379-3.124 22.628-9.372 12.496-12.497 12.496-32.759 0-45.256L166.488 512l337.373-337.373c12.496-12.497 12.496-32.758 0-45.255-12.498-12.497-32.758-12.497-45.256 0l-360 360c-12.496 12.497-12.496 32.758 0 45.255l360 360c6.249 6.249 14.439 9.373 22.628 9.373z" /></svg>     
    </li>
    <li class="right" @click="move(600, -1)">
     <svg class="icon" width="30px" height="30.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path fill="#ffffff" d="M557.179 904c-8.189 0-16.379-3.124-22.628-9.372-12.496-12.497-12.496-32.759 0-45.256L871.924 512 534.551 174.627c-12.496-12.497-12.496-32.758 0-45.255 12.498-12.497 32.758-12.497 45.256 0l360 360c12.496 12.497 12.496 32.758 0 45.255l-360 360c-6.249 6.249-14.439 9.373-22.628 9.373z" /></svg>     
    </li>
   </ul>
   <ul class="dots">
    <li v-for="(dot, i) in sliders" :key="i" 
    :class="{dotted: i === (currentIndex-1)}"
    >
    </li>
   </ul>
  </div>
 </div>
</template>

<script>
export default {
 name: 'slider',
 data () {
  return {
   sliders:[
    {
     img:'../../static/images/1.jpg'
    },
    {
     img:'../../static/images/2.jpg'
    },
    {
     img:'../../static/images/3.jpg'
    },
    {
     img:'../../static/images/4.jpg'
    },
    {
     img:'../../static/images/5.jpg'
    }
   ],
   currentIndex:1,
   distance:-600,
   transitionEnd: true
  }
 },
 computed:{
  containerStyle() {
   return {
    transform:`translate3d(${this.distance}px, 0, 0)`
   }
  }
 },
 methods:{
  move(offset, direction) {
   if (!this.transitionEnd) return
   this.transitionEnd = false
   direction === -1 ? this.currentIndex++ : this.currentIndex--
   if (this.currentIndex > 5) this.currentIndex = 1
   if (this.currentIndex < 1) this.currentIndex = 5

   const destination = this.distance + offset * direction
   this.animate(destination, direction)
  },
  animate(des, direc) {
   if (this.temp) { 
    window.clearInterval(this.temp)
    this.temp = null 
   }
   this.temp = window.setInterval(() => {
    if ((direc === -1 && des < this.distance) || (direc === 1 && des > this.distance)) {
     this.distance += 30 * direc
    } else {
     this.transitionEnd = true
     window.clearInterval(this.temp)
     this.distance = des
     if (des < -3000) this.distance = -600
     if (des > -600) this.distance = -3000
    }
   }, 20)
  }
 }
}
</script>

接下來我們要實(shí)現(xiàn)點(diǎn)擊下面的小圓點(diǎn)來實(shí)現(xiàn)過渡和圖片切換。

<ul class="dots">
  <li v-for="(dot, i) in sliders" :key="i" 
  :class="{dotted: i === (currentIndex-1)}"
  @click = jump(i+1)>
  </li>
</ul>

在點(diǎn)擊小圓點(diǎn)的時(shí)候我們調(diào)用 jump 函數(shù),并將索引 i+1 傳給它。 這里需要特別注意,小圓點(diǎn)的索引和圖片對(duì)應(yīng)的索引不一致,圖片共7張,而5個(gè)小圓點(diǎn)對(duì)應(yīng)的是圖片中中間的5張,所以我們才傳 i+1 。

jump(index) {
  const direction = index - this.currentIndex >= 0 ? -1 : 1 //獲取滑動(dòng)方向 
  const offset = Math.abs(index - this.currentIndex) * 600  //獲取滑動(dòng)距離
  this.move(offset, direction)
}

上面的代碼有一個(gè)問題,在jump函數(shù)里調(diào)用move方法,move里對(duì)于currentIndex的都是 +1 ,而點(diǎn)擊小圓點(diǎn)可能是將 currentIndex 加或者減好多個(gè),所以要對(duì)move里的代碼修改下:

direction === -1 ? this.currentIndex += offset/600 : this.currentIndex -= offset/600

改一行,根據(jù)offset算出currentIndex就行了。

但是又有一個(gè)問題,長(zhǎng)距離切換速度太慢,如下:

使用Vue怎么制作一個(gè)圖片輪播組件 

所以我們需要控制一下速度,讓滑動(dòng)一張圖片耗費(fèi)的時(shí)間和滑動(dòng)多張圖片耗費(fèi)的時(shí)間一樣,給move和animate函數(shù)添加一個(gè)speed參數(shù),還要再算一下:

jump(index) {
  const direction = index - this.currentIndex >= 0 ? -1 : 1
  const offset = Math.abs(index - this.currentIndex) * 600
  const jumpSpeed = Math.abs(index - this.currentIndex) === 0 ? this.speed : Math.abs(index - this.currentIndex) * this.speed 
  this.move(offset, direction, jumpSpeed)
}

六、自動(dòng)播放與暫停

前面的寫的差不多了,到這里就非常簡(jiǎn)單了,寫一個(gè)函數(shù)play:

play() {
  if (this.timer) {
    window.clearInterval(this.timer)
    this.timer = null
  }
  this.timer = window.setInterval(() => {
    this.move(600, -1, this.speed)
  }, 4000)
}

除了初始化以后自動(dòng)播放,還要通過mouseover和mouseleave來控制暫停與播放:

stop() {
  window.clearInterval(this.timer)
  this.timer = null
}

七、 兩處小坑

1. window.onblur 和 window.onfocus

寫到這里,基本功能都差不多了。但是如果把頁面切換到別的頁面,導(dǎo)致輪播圖所在頁面失焦,過一段時(shí)間再切回來會(huì)發(fā)現(xiàn)輪播狂轉(zhuǎn)。原因是頁面失焦以后,setInterval停止運(yùn)行,但是如果切回來就會(huì)一次性把該走的一次性走完。解決的方法也很簡(jiǎn)單,當(dāng)頁面失焦時(shí)停止輪播,頁面聚焦時(shí)開始輪播。

window.onblur = function() { this.stop() }.bind(this)
window.onfocus = function() { this.play() }.bind(this)

2. window.setInterval() 小坑

當(dāng)定時(shí)器 window.setInterval() 在多個(gè)異步回調(diào)中使用時(shí),就有可能在某種機(jī)率下開啟多個(gè)執(zhí)行隊(duì)列, 所以為了保險(xiǎn)起見,不僅應(yīng)該在該清除時(shí)清除定時(shí)器,還要在每次使用之前也清除一遍 。

八、用props簡(jiǎn)單寫兩個(gè)對(duì)外接口

props: {
  initialSpeed: {
   type: Number,
   default: 30
  },
  initialInterval: {
   type: Number,
   default: 4
  }
},
data() {
  ......
  speed: this.initialSpeed  
},
computed:{
  interval() {
    return this.initialInterval * 1000
  }
}

然后再在相應(yīng)的地方修改下就可以了。

完整的代碼如下:

<template>
 <div id="slider">
  <div class="window" @mouseover="stop" @mouseleave="play">
   <ul class="container" :>
    <li>
     <img :src="sliders[sliders.length - 1].img" >
    </li>
    <li v-for="(item, index) in sliders" :key="index">
     <img :src="item.img" >
    </li>
    <li>
     <img :src="sliders[0].img" >
    </li>
   </ul>
   <ul class="direction">
    <li class="left" @click="move(600, 1, speed)">
     <svg class="icon" width="30px" height="30.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path fill="#ffffff" d="M481.233 904c8.189 0 16.379-3.124 22.628-9.372 12.496-12.497 12.496-32.759 0-45.256L166.488 512l337.373-337.373c12.496-12.497 12.496-32.758 0-45.255-12.498-12.497-32.758-12.497-45.256 0l-360 360c-12.496 12.497-12.496 32.758 0 45.255l360 360c6.249 6.249 14.439 9.373 22.628 9.373z" /></svg>     
    </li>
    <li class="right" @click="move(600, -1, speed)">
     <svg class="icon" width="30px" height="30.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path fill="#ffffff" d="M557.179 904c-8.189 0-16.379-3.124-22.628-9.372-12.496-12.497-12.496-32.759 0-45.256L871.924 512 534.551 174.627c-12.496-12.497-12.496-32.758 0-45.255 12.498-12.497 32.758-12.497 45.256 0l360 360c12.496 12.497 12.496 32.758 0 45.255l-360 360c-6.249 6.249-14.439 9.373-22.628 9.373z" /></svg>     
    </li>
   </ul>
   <ul class="dots">
    <li v-for="(dot, i) in sliders" :key="i" 
    :class="{dotted: i === (currentIndex-1)}"
    @click = jump(i+1)
    >
    </li>
   </ul>
  </div>
 </div>
</template>
<script>
export default {
 name: 'slider',
 props: {
  initialSpeed: {
   type: Number,
   default: 30
  },
  initialInterval: {
   type: Number,
   default: 4
  }
 },
 data () {
  return {
   sliders:[
    {
     img:'../../static/images/1.jpg'
    },
    {
     img:'../../static/images/2.jpg'
    },
    {
     img:'../../static/images/3.jpg'
    },
    {
     img:'../../static/images/4.jpg'
    },
    {
     img:'../../static/images/5.jpg'
    }
   ],
   currentIndex:1,
   distance:-600,
   transitionEnd: true,
   speed: this.initialSpeed
  }
 },
 computed:{
  containerStyle() {
   return {
    transform:`translate3d(${this.distance}px, 0, 0)`
   }
  },
  interval() {
   return this.initialInterval * 1000
  }
 },
 mounted() {
  this.init()
 },
 methods:{
  init() {
   this.play()
   window.onblur = function() { this.stop() }.bind(this)
   window.onfocus = function() { this.play() }.bind(this)
  },
  move(offset, direction, speed) {
   if (!this.transitionEnd) return
   this.transitionEnd = false
   direction === -1 ? this.currentIndex += offset/600 : this.currentIndex -= offset/600
   if (this.currentIndex > 5) this.currentIndex = 1
   if (this.currentIndex < 1) this.currentIndex = 5
   const destination = this.distance + offset * direction
   this.animate(destination, direction, speed)
  },
  animate(des, direc, speed) {
   if (this.temp) { 
    window.clearInterval(this.temp)
    this.temp = null 
   }
   this.temp = window.setInterval(() => {
    if ((direc === -1 && des < this.distance) || (direc === 1 && des > this.distance)) {
     this.distance += speed * direc
    } else {
     this.transitionEnd = true
     window.clearInterval(this.temp)
     this.distance = des
     if (des < -3000) this.distance = -600
     if (des > -600) this.distance = -3000
    }
   }, 20)
  },
  jump(index) {
   const direction = index - this.currentIndex >= 0 ? -1 : 1
   const offset = Math.abs(index - this.currentIndex) * 600
   const jumpSpeed = Math.abs(index - this.currentIndex) === 0 ? this.speed : Math.abs(index - this.currentIndex) * this.speed 
   this.move(offset, direction, jumpSpeed)
  },
  play() {
   if (this.timer) {
    window.clearInterval(this.timer)
    this.timer = null
   }
   this.timer = window.setInterval(() => {
    this.move(600, -1, this.speed)
   }, this.interval)
  },
  stop() {
   window.clearInterval(this.timer)
   this.timer = null
  }
 }
}
</script>

關(guān)于使用Vue怎么制作一個(gè)圖片輪播組件問題的解答就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關(guān)注創(chuàng)新互聯(lián)成都網(wǎng)站設(shè)計(jì)公司行業(yè)資訊頻道了解更多相關(guān)知識(shí)。

另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務(wù)器15元起步,三天無理由+7*72小時(shí)售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國(guó)服務(wù)器、虛擬主機(jī)、免備案服務(wù)器”等云主機(jī)租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡(jiǎn)單易用、服務(wù)可用性高、性價(jià)比高”等特點(diǎn)與優(yōu)勢(shì),專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場(chǎng)景需求。

網(wǎng)站名稱:使用Vue怎么制作一個(gè)圖片輪播組件-創(chuàng)新互聯(lián)
文章源于:http://muchs.cn/article18/pojdp.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站設(shè)計(jì)移動(dòng)網(wǎng)站建設(shè)、企業(yè)建站、做網(wǎng)站、外貿(mào)網(wǎng)站建設(shè)、微信公眾號(hào)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

網(wǎng)站托管運(yùn)營(yíng)