基於vue實現上下滑動翻頁效果
18年年底的時候,一直在做年度報告的H5頁面,因為專案需要,需要實現上下滑動翻頁,並且上滑的頁面比正常頁面的比例要縮小一定比例。
效果類似於http://www.17sucai.com/pins/demo-show?id=7834,這個連結是基於jquery實現的,我寫的是和這個例子效果一樣,只不過是用vue實現的。
程式碼地址:https://github.com/dreamITGirl/vuepageturn //demo
首先介紹一下,這個專案依賴的外掛:上下滑動翻頁使用了v-touch,是基於hammer.js進行的vue封裝。也可以不用這個外掛寫,直接用js原生,通過touchStart,touchMove,touchEnd來實現也是可以的;
現在總結一下幾點,是我在寫程式碼的時候遇到的坑。
1、因為我是使用的是v-touch裡的pan屬性及它附帶的方法和事件。所以,在元件內部如果還有滾動的區域,就可能會出現衝突,最後專案上線之前,仍沒有徹底解決。
不管是用v-touch還是用js原生,都會出現這個問題,在實現上下頁面滑動切換時,採用了純css去控制上下滑動的距離。所以,css可能會衝突。所以,建議不要在使用v-touch或者js原生滾動區域內部再次出現滾動區域。
下一篇部落格會重點說一下這個問題的解決方式。
<v-touch class="container" @panstart.prevent="panStart" @panmove.prevent="panMove" @panend.prevent="panEnd"> <component v-for="(val,index) in componentList" :key="index" :is="val" :style="{ zIndex:zIndex(index), top:top(index), transition:`all ${transition(index)}s`, transform:`translateY(${top(index)}) scale3d(${scale(index)},1,${scale(index)})` }" ></component> </v-touch>
如果在component中仍有滑動的區域的話,就會產生css衝突。
2、滾動距離的計算
看圖理解
頁面1,頁面2,頁面3分別對應我要上下滑動切換的頁面,並且,1,2,3分別對應元件中的三個元件,也就是說,每個頁面都是一個獨立的元件。而這些元件是通過v-for的方式迴圈渲染的。
需要控制的是每個頁面的top值,z-index值,scale值,以及為了實現平滑的效果transition的過渡時間。
當頁面向上(下)滑動時,頁面3(頁面1)就變成了當前展示的頁面,頁面2就變成了前一個頁面(下一個頁面),因為頁面3(頁面1)是最後(第)一個頁面了,使用者不能再繼續向下滑,
所以,我們需要在panmove和panend時去依據當前的index值和當前展示的元件陣列中最後一項和第一項去判斷
重點說一下在panmove的時候,也就是在滾動過程中的時候,頁面的變化以及top值和滑動的距離是如何計算的。還是看圖:
這個裡面最難理解的就是這個上滑,或者下滑的距離,在我的程式碼裡,1.0版本的並沒有解決兩個頁面始終差一段距離,這個距離就是distance的2/3,在panend的時候,我們需要看一下使用者滑動的距離是不是可以翻頁,如果距離很小,則不能翻頁,最好加一下判斷。
上滑之後,頁面1就變成了其他頁面,頁面2變成了前一個頁面,頁面3變成了當前頁面,對這3個頁面來說,它們各向上走了一個螢幕的高度,而頁面3的高度top值變成了0,頁面2變成了-1*螢幕的高度。頁面1則變成了-2 * 螢幕的高度,但是對於頁面1來說,已經變成了其他的圖片,所以它的高度,是(它的index-當前的index)*螢幕的高度。
對於當前上滑(下滑)的頁面縮放的解決,是在panstart的時候,設定當前頁面的縮放率為1,在panmove的時候根據滑動的距離,隨機設定縮放率。在panend的時候,設定延遲,使縮放率變成。
所以,正常的滑動過程中的樣式是
具體的程式碼,大家可以去github上自行下載使用,如果不使用v-touch,也可以用touchStart,touchMove,touchEnd分別對應顯示。