摘要:其次父組件中負責通用的功能,以及輪播的整體架構,其結構如下。下面的是一種移動端的適配方案。接下來實現函數運用動畫切換到指定下標的子項到此為止,咱們就已經完成了一個初步的滑動切換輪播圖的功能了。
前言
昨天寫了一篇側邊菜單組件的文章,閱讀人數挺多的,內心很欣喜(偷著樂,第一篇文章有這么多人看)!乘著這股勁,今天在繼續寫一篇我們平時工作中更常用的滑動輪播組件的文章。
效果展示老規矩,咱們先看做成后的效果,然后咱們再一步步的開始制作:
在實際的工作中,咱們輪播中的內容形式可能有很多種:圖片、文本、視頻、其他DOM結構等。所以咱們的輪播組件必須能滿足這幾種應用情況。那么我們可以把組件分兩部分:
可以高度定制的子組件,負責渲染輪播中的每一個子項
負責輪播的父組件,用來處理通用的滑動事件、自動輪播、指示器等功能
我們現在這定義子組件的名稱為swiper-item;父組件名稱為swiper
DOM組成首先咱們的子組件中負責渲染自定義的內容,則子組件中需要一個插槽slot。
swiper-item:
其次父組件中負責通用的功能,以及輪播的整體架構,其DOM結構如下。
swiper:
默認插槽在使用的時候渲染咱們輪播的子項,通常為swiper-item;indicator插槽用來自定義指示器的樣式,因為在實際使用過程中指示器樣式很可能是需要定制的。
css樣式移動端的視圖大小有限,子項的大小一般是父組件的全部可視視圖。
swiper-item:
下面的vw是一種移動端的適配方案(https://www.w3cplus.com/css/t...)。其他的適配方案還有淘寶的flexible,這個css大家根據自己的適配方案更改下,這里不做過多描述,大家感興趣的自行百度。
swiper:
老規矩,寫JS代碼前咱們先理清交互邏輯:
頁面渲染開始,首先把所有子組件掛載到DOM上,當所有子節點掛載好了后初始化父組件
同理,當輪播組件銷毀的時候先銷毀子組件,再銷毀父組件
初始化的時候需要:
獲取父組件容器DOM節點、以及父組件節點的寬度
獲取到所有子組件節點
給所有子節點依次設置好初始坐標
給父節點綁定touch事件
初始化完成后,當手指觸摸到屏幕瞬間,記錄當前手指起始的坐標
當手指移動的過程中,阻止頁面中的默認事件,根據當前坐標以及起始坐標計算手指X、Y軸移動的距離
如果X軸移動比Y軸多則判斷手指在橫向移動,否則為豎向移動
如果橫向移動則移動子項中的位置,修改所有子項的坐標
手指離開屏幕的時候判斷手指移動總距離,如果大于一個臨界值則輪播切換到下一屏或者上一屏(根據滑動方向判定),否則重置會原始狀態
swiper-item:
export default { mounted () { this.$nextTick(() => { this.$parent.init() }) }, beforeDestroy () { this.$nextTick(() => { this.$parent.destroy() }) } }
swiper:
初始化完成后,咱們接下來編寫咱們的moveStart、moving、moveEnd三個touch事件,在methods中完善這三個函數,并添加一個臨界值sensitivity以及一個阻力系數,阻力系數有啥用,注意看下面代碼的注釋:
data () { return { sensitivity: 60, resistance: 0.3 } }, methods: { moveStart (e) { this.start.x = e.changedTouches[0].pageX this.start.y = e.changedTouches[0].pageY this.setTransition("none") }, moving (e) { e.preventDefault() e.stopPropagation() let distanceX = e.changedTouches[0].pageX - this.start.x let distanceY = e.changedTouches[0].pageY - this.start.y if (Math.abs(distanceX) > Math.abs(distanceY)) { this.isMoving = true this.move.x = this.start.x + distanceX this.move.y = this.start.y + distanceY // 當活動子項為第一項且手指向右滑動或者活動項為最后一項切向左滑動的時候,添加阻力,形成一個拉彈簧的效果 if ((this.active === 0 && distanceX > 0) || (this.active === (this.items.length - 1) && distanceX < 0)) { distanceX = distanceX * this.resistance } this.setTransform(distanceX) } }, moveEnd (e) { if (this.isMoving) { e.preventDefault() e.stopPropagation() let distance = this.move.x - this.start.x if (Math.abs(distance) > this.sensitivity) { if (distance < 0) { this.next() } else { this.prev() } } else { this.back() } this.reset() this.isMoving = false } }, // 切換下一屏 next () {}, // 切換下一屏 prev () {}, // 如果滑動達不到閾值,所有元素重置回之前狀態 back () {}, // 重置動畫中用到的一些變量 reset () {}, destroy () { this.setTransition("none") } }
接下來咱們完善下next、prev、back、reset函數:
next () { let index = this.active + 1 // 運用動畫切換到指定下標的子項 this.go(index) }, prev () { let index = this.active - 1 // 運用動畫切換到指定下標的子項 this.go(index) }, reset () { this.start.x = 0 this.start.y = 0 this.move.x = 0 this.move.y = 0 }, back () { this.setTransition() this.setTransform() }, go (index) {}
go函數用來做輪播切換的效果。我們在寫代碼的過程中,可以先定義一個函數來做某個事情,然后再后面用代碼來實現邏輯,這樣的咱們寫代碼過程中的思路就會很清晰。接下來實現go函數:
// 運用動畫切換到指定下標的子項 go (index) { this.active = index if (this.active < 0) { this.active = 0 } else if (this.active > this.items.length - 1) { this.active = this.items.length - 1 } this.$emit("change", this.active) this.setTransition() this.setTransform() }
到此為止,咱們就已經完成了一個初步的滑動切換輪播圖的功能了。但是很多時候,我們的輪播是需要自動播放的,那么如何在現在的基礎上增加自動輪播呢?請大家自己思考下,哈哈。下面我們把當前代碼整合下:
寫在最后
今天寫這篇文章的時候發現有兩個兄弟給我微信轉了錢,很謝謝這兩個兄弟,感謝你們的支持。其實說實話,我花心思寫這個主要目的不是為了錢,而是興趣,否則我用這個時間用來做點私活什么的收入比這個多多了。只是看到大家的支持,內心很有成就感,盡管很多時候只有1分錢,所以也希望大家有錢的捧個錢場,沒錢的捧個人場,哈哈。(未完待續...)
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/93270.html
摘要:最后提醒下,代碼中使用而非的原因是為了啟動移動端手機的動畫加速,提升動畫流暢度。 前言 最近面試發現很多前端程序員都從來沒有寫過插件的經驗,基本上都是網上百度。所以打算寫一系列文章,手把手的教一些沒有寫過組件的兄弟們如何去寫插件。本系列文章都基于VUE,核心內容都一樣,會了之后大家可以快速的改寫成react、angular或者是小程序等組件。這篇文章是第一篇,寫的是一個類似QQ的側邊菜...
摘要:前言在我們移動端還有一個很常用的組件,那就是滑動加載更多組件。平常我們看到的很多插件實現相當復雜就覺得這個組件很難,其實不是的這個組件其實可以很簡單的就實現出來,而且體驗也能非常的棒當然我們沒有實現下拉刷新功能下面我們就一起來實現這個組件。 前言 在我們移動端還有一個很常用的組件,那就是滑動加載更多組件。平常我們看到的很多插件實現相當復雜就覺得這個組件很難,其實不是的!!這個組件其實可...
閱讀 1985·2021-11-22 14:45
閱讀 2592·2021-10-12 10:11
閱讀 767·2021-09-22 10:02
閱讀 1196·2019-08-30 15:55
閱讀 1141·2019-08-30 15:54
閱讀 3247·2019-08-30 15:54
閱讀 1180·2019-08-29 17:16
閱讀 3080·2019-08-28 17:55