Vue實現的滑動切換路由組件

前言

前段時間呢實現了一個模仿移動端app的經過滑動來切換路由/tab的效果,詳見vuejs實現spa頁面組件滑動特效。完了以後呢就在想能不能作成一個組件的形式,改進一下,抽離出來,順便再發布到npm上,不是美滋滋?這兩天正好有時間,就把它寫出來了,我給他起名叫tab-slider,中間遇到一些坑,分享一蛤。css

正文

簡單介紹

正如我上一篇文章所說,若是你須要這種功能vue

  1. 即將離開的組件和將要進入的組合須要同時出如今頁面中
  2. 用手指拖動頁面能夠切換路由,而不單單是點擊連接跳轉
  3. 結合以上兩點,拖動過程當中同時顯示兩個組件,手指離開屏幕後執行切換路由或者返回的動做

tab-slider也許能夠知足你,具體實現思路能夠去看上一篇文章,這裏就不講了,來看一下效果圖:
預期效果webpack

改進方面

  • 相比以前每一個路由組件都要寫touch事件的蠢寫法,我把touch事件寫在了router-view上,加強了代碼的複用,事實上不這麼改我也無法將組件抽離出來給別人用
  • 支持多個tab切換,以前是隻有2個,寫法固定,如今能夠有任意個tab切換。

踩過的坑

在我開發XiXi這個仿DiDi app項目的時,我使用的Vue版本是2.4.4,而我寫tab-slider的時候使用了最新版本的Vue 2.5.16。寫完以後我遇到了一個問題,滑動完畢切換路由的時候,router-view所對應的區域會閃一下,而經過點擊router-link切換路由則不會。
Vue2.5.16效果圖:
實際效果git

where?哪有問題?

這裏一開始我以爲多是新老項目css樣式作了部分更改,影響了瀏覽器的重繪或是迴流,苦苦搜尋無果。後來經過chrome控制檯的的performance發現:新版本的vue多了個flushCallbacksactivity,耗時9ms。這是什麼?繼續google,沒什麼有用的東西,ok不要緊,去Vue倉庫裏搜,發現他第一次寫入是在14 Oct 2017,也就是Vue2.5.2發佈的時候,這個版本修改了nextTick實現機制,並關閉了一個issue,有興趣的同窗能夠看看。這個issue下面呢又有人reference了這個issue,裏面正好講解了相關內容。開源社區簡直棒極了!github

why?問題是什麼?

簡單來講呢就是新版Vue對於DOM相關事件是放在macro task裏,其餘狀況默認走micro task,而micro task要先於macro task執行。而我項目中的寫法是,對拖曳的dom監聽了transitionend事件,當transition結束後進行路由切換。因此緣由應該是滑動結束後(也就是transition結束),路由沒有在第一時間進行跳轉,因此出現了一瞬間的「白屏」,在咱們看來就是閃了一下。web

how?怎麼解決?

  • solution1: 使用低版本Vue,2.4.4及如下。
  • solution2: 修改寫法,直接使用settimeout,延遲時間與動畫時間一致,而因爲js的異步機制,實際延遲時間老是略大於寫入的延遲時間,基本上能達到想要的效果。

這裏我採用了solution2,畢竟是寫出來給人用了,總要有個通用的解決方案。chrome

另外個坑就是在發佈到npm以後,引入個人包,無法正常使用,提示組件未註冊,折騰了許久,參考了vantcube-ui的組件導出方式,卻一直沒能成功導出正確的對象。最後發現緣由在於webpack的配置上: 須要在output屬性中添加library以及libraryTarget,這樣才能正確導出對象。vue-cli

怎麼用

說了那麼多廢話,這組件怎麼用?npm

  • 安裝:npm i -S tab-slider
  • main.js中引入樣式,import 'tab-slider/dist/index.css'
  • 在須要的組件中註冊子組件,import TabSlider from 'tab-slider',也能夠在main.js中引入,並經過Vue.use()來使之成爲一個全局組件。
  • 接受一個comp的prop,類型是數組,數組中的每一項是對象,對象中又包含了namecomponent屬性。其中name屬性必須和路由名字相同,(這也意味着你必須爲每一個路由取名),component則是對應的組件。這裏要注意一下,comp中每一項的順序須要與你的router-link順序一一對應。
  • 還接受一個default-index,表示默認跳轉的路由,從0開始。

能夠改進的地方

  • webpack相關配置仍是經過vue-cli生成的,刪除了一些沒必要要的東西,但仍是沒有作到最簡。打包出來的東西也有9kb,好像有點大的過度。
  • 能夠把router-link的內容也直接作進去,畢竟tab和內容區是緊密聯繫的。
  • 提供更多的選項(prop)給使用者。

麼得了

若是對你有幫助的話點個贊點個收藏點個star提個issue都是能夠的哦 倉庫地址segmentfault

相關文章
相關標籤/搜索