一個基於Vue的圖片輪播元件的實現

zhangxiaoshang發表於2018-05-03

1. 線上DEMO

va-carousel.xiaoshang.online

Github

2. 首先是一張思維導圖

導圖

3. 然後是以上屬性的標註說明

標註

4. 程式碼層

4.1 除去可從父元件接收的屬性,元件自身有以下屬性:

data() {
    return {
      list: [],     // 當前顯示的圖片列表
      hover: false, // 滑鼠是否懸浮在元件上
      timer: null,  // 自動切換的 setInterval
      itemWidth: '',// 每項元素的寬度
      isReverse: false // 是否是反向切換,觸發prev時,該屬性為true
    }
  }
複製程式碼

4.2 元件掛載之前

  1. 計算每項元素的寬度,即itemWidth的值
  2. 初始化顯示的圖片列表,即list。這裡儲存的資料才是真正會被在頁面上渲染的。每次切換,實際上就是修改該list中的資料,對應的檢視會自動更新,資料驅動檢視嘛。
beforeMount() {
    this.itemWidth = 100 / this.total + '%'
    this.list = this.items.slice(0, this.total)
  },

複製程式碼

4.3 元件掛在後,檢查autoplay屬性,若該屬性為true,則產生一個計時器

mounted() {
    if (this.autoplay) {
      this.startTimer()
    }
  },
複製程式碼

4.4 startTimer函式很簡單,就是間隔一定時間觸發一次next(向後)切換

// 開始計時器
startTimer() {
    if (!this.interval || this.interval <= 0) {
        return
    }
    this.timer = setInterval(this.next, this.interval)
}
複製程式碼

4.5 next函式

    // 下一張
    next() {
      // 如果圖片列表小於需要顯示的數量,則不進行滾動
      if (this.items.length < this.total) {
        return
      }

      // 向後追加一個元素,該元素為:
      // 顯示列表中最後一個元素在原陣列中的後一個元素
      // 如果已經是最後一個元素,則使用第一個元素

      let indexOfItems = this.items.findIndex(
        item => item.id === this.list[this.list.length - 1].id
      )

      if (indexOfItems === this.items.length - 1) {
        // 使用第一個元素
        this.list.push(this.items[0])
      } else {
        // 使用後一個元素
        this.list.push(this.items[indexOfItems + 1])
      }
      // 移除當前顯示圖片中的第一個
      this.list.shift()
      this.isReverse = false
    },
複製程式碼

4.6 對應的還有一個prev函式,與next函式邏輯相反,這裡就不展示程式碼了

4.7 點選圖片時,向父元件釋放事件selectedItem,傳遞兩個引數 item 和 index 分別為當前點選的物件,和該物件在list中的位置

    // 點選圖片
    selectedItem(item, index) {
      this.$emit('selectedItem', item, index)
    },
複製程式碼

4.8 滑鼠懸浮在元件上時,停止自動切換(若autoplay為ture), 滑鼠離開時,繼續切換

    handleMouseEnter() {
      this.hover = true
      this.pauseTimer()
    },

    handleMouseLeave() {
      this.hover = false
      if (this.autoplay) {
        this.startTimer()
      }
    },
複製程式碼

4.9 然後是過渡效果的實現

因為arrow元素也在transition-group中,所以當arrow=‘hover’時,arrow的顯示、隱藏也會觸發鉤子函式,但是我們的鉤子函式是針對image-item寫的,所以需要在函式中檢測是哪個元素觸發的,這裡通過檢查className進行判斷。 然後針對向前、向後兩種情況設定不同的樣式

 beforeEnter(el) {
      // 只對image-item使用過渡
      let isImageItem = el.className.indexOf('image-item') > -1
      if (isImageItem) {
        el.style.opacity = 0
        if (this.isReverse) {
          el.style.transform = 'translateX(-100%)'
        } else {
          el.style.transform = 'translateX(100%)'
        }
      }
    }
複製程式碼

4.10 這裡使用了Velocity,這是一個實現動畫效果的js庫,之所以使用這個庫是因為試了n種方案都沒能實現預期效果emm

enter(el, done) {
      // 只對image-item使用過渡
      let isImageItem = el.className.indexOf('image-item') > -1
      if (isImageItem) {
        Velocity(el, { opacity: 1, translateX: '0px' }, { complate: done })
      } else {
        done()
      }
    }
複製程式碼

4.11 然後是對應的beforeLeave、leave函式,這裡就不展示了

以上基本就是所有js部分,整體感受就是,一旦實現邏輯搞清楚,程式碼實現起來還是挺容易的,然後就是框架的熟悉程度。

5. npm包釋出

這本是公司業務中的一個功能需求,因為沒能在網上找到現成的輪子,找個差不多的效果領導不滿意,所以只能自己寫了,做都做了不發出來豈不是白寫了. . .

npm釋出流程簡單概括就是

1.註冊

去npm官網註冊個賬號

2.生成npm包 資料夾中有package.json檔案就是一個npm包

3.在終端使用npm publish釋出包,成功之後,該專案資料夾下所有檔案都會上傳至npm官網,當使用者使用npm install安裝後,就會將整個資料夾下載至node_modules資料夾中,對於這個專案,就是一個使用vue-cli生成的vue專案,元件路徑src/components/VaCarousel.vue,所以使用npm install va-carousel安裝之後,只需要在專案中像這樣匯入即可使用(前提是你的專案也是使用vue-cli生成的,對於其他方式建立的專案可能會出現一些錯誤):import VaCarousel from 'va-carousel/src/components/VaCarousel.vue'

以上

相關文章