一个类似于京东Plus权益引见的小功用

近来公司要开辟一套线上付费的会员App,是和原生一同混合式的开辟,有一个会员权益模块是悉数运用H5开辟,想给人人看下须要做成的案例:

《一个类似于京东Plus权益引见的小功用》

实在没什么难点,重要就是功用有:
1、顶部导航栏能够摆布滑动,点击某一个栏目按钮内容随着切换;
2、而且加载一次以后,第二次就从新加载;
3、被点击的栏目按钮居中显现,摆布会追随点击的位置转动
4、手机物理返回按键对路由的影响

觉得本身表达不是迥殊的清晰,来一张动图把:

《一个类似于京东Plus权益引见的小功用》

好了 空话不多说 最先说代码相干的东西了:

顶部导航的完成计划:

运用 swiper3 完成导航回弹和摆布滑动效果

《一个类似于京东Plus权益引见的小功用》

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的轮回衬着li

swiper.js的挪用:

               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)
                    }

                })

上面的代码就能够完成1、3的请求了 我上传的代码不是很全,细节代码我会附上github地点。

我们接下来看第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会一步一步的返回,明显,这不是我们要的效果,我们要的效果应当是“指哪打哪,自我掌控

1、起首,我们新建一个 global变量 这个用于纪录路由的接见泉源

《一个类似于京东Plus权益引见的小功用》

2、在对应的路由文件内里增加路由卫士:

《一个类似于京东Plus权益引见的小功用》

3、在mounted内里设置popstate和设置goBack要领:

《一个类似于京东Plus权益引见的小功用》

4、烧毁组件的时刻 移除popstate

《一个类似于京东Plus权益引见的小功用》

我的三个路由的称号分别为:mpos、payPhoneBill、movieTicket,接下来看动图:

《一个类似于京东Plus权益引见的小功用》

能够看到 我们只须要推断 global.beforeRouteName 和 路由的称号作为推断前提,就能够做任何操作和交互了,能够本身很好的掌握物理键啦!

demo在线预览:

《一个类似于京东Plus权益引见的小功用》

demo的代码地点:https://github.com/yulongwuko…

    原文作者:dragonจุ๊บ
    原文地址: https://segmentfault.com/a/1190000018474013
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞