uni-app導航欄+swiper,及處理滑動衝突 第一部分:swiper + 頂部/底部導航欄實現 第二部分:滑動衝突處理

第一部分:swiper + 頂部/底部導航欄實現

這裏的思想與安卓的fragment+viewpager是很類似的,用swiper作爲左右滾動區間,聯動tab導航欄,中間展示內容組件化

導航欄部分大家可以自定義,我整個界面採用的是底部導航欄用position:fixed浮動,swiper部分的current注意是與tab的下標一致,並且注意swiper的高度一定要動態自適應,這個等下滑動衝突會講到。swiper-item內部內容是抽成組件化了,這樣代碼看着更整潔規範,注意內部class一定要寫。

一個簡單的swiper聯動導航欄例子就好了,當然只是簡單的,因爲實際上還有不少問題。

第二部分:滑動衝突處理

如果你按照上面自己敲出來一個demo 你就會發現,如果你的頁面內容過長涉及滾動,你的組件內就根本就不能滾動,原理是這些組件的父組件是swiper這貨,而swiper樣式中本身是不支持上下滑動滴,當然這個也好處理,我們在樣式中加入:

/deep/ uni-swiper .uni-swiper-wrapper {

overflow-y: auto !important;

}

/deep/ uni-swiper-item {

overflow-y: auto !important;

}

加完了滾動以後你就會驚喜的發現頁面滾動上去以後再也下不來了!因爲下拉事件被原生的下拉刷新佔用咯~   你想着這還不簡單,我加個scrollview還不行麼,那你試試吧真不行嘿嘿!

首先讓我告訴你原理:我們的swiper這貨是必須有高度的, 而由於swiper高度是固定的,導致就算組件內部內容已經過長了,但下拉的時候body其實並沒有過長,因此,無論你是什麼scrollview或者overflow:auto,都會優先觸發body滾動,也就是下拉刷新,這就是造成衝突的主要原因,我可以用一張圖更清晰的解釋:

針對這點,網上一種解決辦法@touch.stop和@touchmove.stop你們可以試一下,反正H5可以,真機上不行,就算真機上可以,但這種方法只會在swiper區域攔截,造成下拉刷新區域很小,用戶體驗也是很差的。所以被我淘汰了。

根據上面的原理圖,我們可以想到,既然swiper內部不能滾動,那就讓swiper自身高度自適應撐起來,這樣就會完美解決問題

所以首先我們需要解決swiper高度自適應問題

這裏給了高度,的確已經解決了初步的問題,但是實際運用中,不可能所有的內容都是一上來就確定的,肯定要有網絡請求在隨時更新內容和高度的,比如有一個列表,那麼上面的代碼就失效了,因爲高度在onReady週期已經定死了。

所以 我們的最後一步 需要隨時更新高度,那麼想到的思路就是子組件中emit通知父組件的swiper更新高度咯,嘗試一下:(我這裏用了個測試box來實驗)

<view style="height: 100px;background-color: #007AFF;" v-show="testShow"></view>

uni.$on('updateSwiperHeight', () => {

console.log('收到通知');

this.getCurrentSwiperHeight('.fragment');

}); //父組件中註冊監聽

父組件在收到通知後會重新獲取子組件高度並更新界面,這是美好的邏輯設想,但實際上獲取dom高度的方法中,此時高度還沒有及時更新,所以我們首先會想到將getCurrentSwiperHeight方法放在this.$nextTick方法中,但是在我的嘗試下 就算包裹在nexttick中,高度也是沒有及時更新,所以我只能使用了最終解決辦法:

使用setTimeout,延遲一段時間再獲取高度,事實證明暫時只有這種方法能獲取到高度。如果大家有什麼更好的辦法,可以留言告訴我謝謝!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章