最近公司要開發一套線上付費的會員App,是和原生一塊兒混合式的開發,有一個會員權益模塊是所有使用H5開發,想給你們看下須要作成的案例:html
其實沒什麼難點,主要就是功能有:
一、頂部導航欄能夠左右滑動,點擊某一個欄目按鈕內容跟着切換;
二、而且加載一次以後,第二次就從新加載;
三、被點擊的欄目按鈕居中顯示,左右會跟隨點擊的位置滾動
四、手機物理返回按鍵對路由的影響vue
感受本身表達不是特別的清楚,來一張動圖把:git
好了 廢話很少說 開始說代碼相關的東西了:github
頂部導航的實現方案:web
使用 swiper3 實現導航回彈和左右滑動效果vue-router
html內容::緩存
<div class="rightsProfile"> <div class="rightsProfile_head"> <div id="nav" class="swiper-container"> <ul class="swiper-wrapper"> <li :key="i" v-for="i in myNavBar" :class="{'active-nav':i.active}" class="swiper-slide"> {{i.title}} </li> </ul> </div> </div> </div>
我使用了vuejs的循環渲染liapp
swiper.js的調用:less
var myNav = new Swiper('#nav', { freeMode: true, freeModeMomentumRatio: 0.5, slidesPerView: '3', }); let swiperWidth = myNav.container[0].clientWidth let maxTranslate = myNav.maxTranslate(); let maxWidth = -maxTranslate + swiperWidth / 2 myNav.on("tap",function(swiper,e){ let slide = swiper.slides[swiper.clickedIndex] let slideLeft = slide.offsetLeft let slideWidth = slide.clientWidth let slideCenter = slideLeft + slideWidth / 2; // 被點擊slide的中心點 myNav.setWrapperTransition(300) if (slideCenter < swiperWidth / 2) { myNav.setWrapperTranslate(0) } else if (slideCenter > maxWidth) { myNav.setWrapperTranslate(maxTranslate) } else { let nowTlanslate = slideCenter - swiperWidth / 2 myNav.setWrapperTranslate(-nowTlanslate) } })
上面的代碼就能夠實現一、3的要求了 我上傳的代碼不是很全,細節代碼我會附上github地址。移動端web
咱們接下來看第2個要求,就是點擊加載一次以後,再次點擊不會從新加載,這裏我使用了vue-router
結構以下:
<template> <div id="page"> <Loading :isLoading="isLoading"></Loading> <div class="rightsProfile"> <div class="rightsProfile_head"> <div id="nav" class="swiper-container"> <ul class="swiper-wrapper"> <li :key="i" v-for="i in myNavBar" :class="{'active-nav':i.active}" class="swiper-slide"> {{i.title}} </li> </ul> </div> </div> </div> <keep-alive> <router-view v-if="$route.meta.keepAlive"> <!-- 這裏是會被緩存的視圖組件,好比 page1,page2 --> </router-view> </keep-alive> <router-view v-if="!$route.meta.keepAlive"> <!-- 這裏是不被緩存的視圖組件,好比 page3 --> </router-view> </div> </template> <style lang="less"> #nav{ height: 100%; .swiper-wrapper{ height: 100%; li{ text-align: center; height: 100%; display: flex; align-items: center; justify-content: center; &.active-nav{ color:#fff; background:#ddd !important; } &.active-nav a{ color:#fff; background:#ddd !important; } } } } </style> <script> import Loading from "@/components/loading"; export default{ data(){ return{ myNavBar:[{ title:"移動機具", active:true, mark:"mpos" },{ title:"8折話費", active:false, mark:"payPhoneBill" },{ title:"5折看電影", active:false, mark:"movieTicket" },{ title:"家用", active:false },{ title:"家用電器", active:false },{ title:"家用", active:false }], routerName:"" } }, components:{ Loading }, watch: { $route(to, from) { // console.log(this.$route.name); let routerName = this.$route.name; this.myNavBar.map((el)=>{ el.active = false; if(el.mark==routerName){ el.active = true; } }); } }, mounted(){ this.$nextTick(()=>{ let that = this; var myNav = new Swiper('#nav', { freeMode: true, freeModeMomentumRatio: 0.5, slidesPerView: '3', }); let swiperWidth = myNav.container[0].clientWidth let maxTranslate = myNav.maxTranslate(); let maxWidth = -maxTranslate + swiperWidth / 2 myNav.on("tap",function(swiper,e){ let slide = swiper.slides[swiper.clickedIndex] let slideLeft = slide.offsetLeft let slideWidth = slide.clientWidth let slideCenter = slideLeft + slideWidth / 2; // 被點擊slide的中心點 myNav.setWrapperTransition(300) if (slideCenter < swiperWidth / 2) { myNav.setWrapperTranslate(0) } else if (slideCenter > maxWidth) { myNav.setWrapperTranslate(maxTranslate) } else { let nowTlanslate = slideCenter - swiperWidth / 2 myNav.setWrapperTranslate(-nowTlanslate) } that.myNavBar.map((el)=>{ el.active = false; }); that.myNavBar[swiper.clickedIndex].active = true; that.$router.push({ path:that.myNavBar[swiper.clickedIndex].mark }) }) }) } } </script>
頭部導航在主路由裏面,router-view顯示每一個欄目對應的內容,能夠給每一個路由設置keep-alive,實現條件3。
從事移動端web開發的小夥伴們應該對手機的物理返回鍵「深惡痛絕」把,一樣咱們作完了上面那個demo,當你點擊安卓的物理返回鍵的時候,demo會一步一步的返回,顯然,這不是咱們要的結果,咱們要的效果應該是「指哪打哪,自我掌控」
一、首先,咱們新建一個 global變量 這個用於記錄路由的訪問來源
二、在對應的路由文件裏面添加路由衛士:
三、在mounted裏面配置popstate和配置goBack方法:
四、銷燬組件的時候 移除popstate
個人三個路由的名稱分別爲:mpos、payPhoneBill、movieTicket,接下來看動圖:
能夠看到 咱們只須要判斷 global.beforeRouteName 和 路由的名稱做爲判斷條件,就能夠作任何操做和交互了,能夠本身很好的控制物理鍵啦!
demo在線預覽:
demo的代碼地址:https://github.com/yulongwuko...