最近公司要开发一套线上付费的会员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...