1. 線上DEMO
2. 首先是一張思維導圖
3. 然後是以上屬性的標註說明
4. 程式碼層
4.1 除去可從父元件接收的屬性,元件自身有以下屬性:
data() {
return {
list: [], // 當前顯示的圖片列表
hover: false, // 滑鼠是否懸浮在元件上
timer: null, // 自動切換的 setInterval
itemWidth: '',// 每項元素的寬度
isReverse: false // 是否是反向切換,觸發prev時,該屬性為true
}
}
複製程式碼
4.2 元件掛載之前
- 計算每項元素的寬度,即itemWidth的值
- 初始化顯示的圖片列表,即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'
以上