zoukankan      html  css  js  c++  java
  • vue实现下拉到不同位置改变导航背景色

    效果图

    src/components/scroll/index.vue

    <template>
        <!-- 通过ref可以获取到dom对象 -->
        <swiper class="swiper" :options="swiperOption" ref="swiper">
          <div class="mine-scroll-pull-down">
              <me-loading :text="pullDownText" inline ref="pullDownLoading" />
          </div>
          <swiper-slide>
              <!-- 所有内容放在插槽里 -->
              <slot></slot>
          </swiper-slide>
          <div class="mine-scroll-pull-up">
              <me-loading :text="pullUpText" inline ref="pullUpLoading" />
          </div>
          <div class="swiper-scrollbar" slot="scrollbar"></div>
      </swiper>
    </template>
    
    <script>
      import { Swiper, SwiperSlide } from 'vue-awesome-swiper';
      import 'swiper/css/swiper.css';
      import MeLoading from 'components/loading';
    
      export default {
        name: 'Scrollbar',
        title: 'Scrollbar',
        components: {
          Swiper,
          SwiperSlide,
          MeLoading
        },
        data() {
          return {
            pulling:false,//是否正在下拉中
            pullDownText:'向下拉动会重新加载幻灯片哦',
            pullUpText:'向上拉动会加载更多哦',
            swiperOption: {
              scrollbar: {
                el: '.swiper-scrollbar',
                hide: true
              },
              direction:'vertical',
              slidesPerView:'auto',
              freeMode:true,
              setWrapperSize:true,
              on:{//下拉刷新时触发的事件
                sliderMove:this.sliderMove,//一开始使用sliderMove,有bug
                touchEnd:this.touchEnd,
                transitionEnd:this.scrollEnd//滚动结束
              }
            },
          }
        },
        props:{
          recommends:{
            type:[Array,Object],
            default(){
              return [];
            }
          }
        },
        watch:{//当recommends值发生改变时
          recommends(){
            this.$refs.swiper && this.$refs.swiper.$swiper.update();//更新滚动条长度
          }
        },
        methods:{
          sliderMove(){
            if(this.pulling) return;//正在下拉中,则不重复下拉
    
            const swiper=this.$refs.swiper.$swiper;
    
            this.$emit("scrolling",swiper.translate,swiper);
    
            if(swiper.translate>0){//向下拉
              if(swiper.translate>100){//超出规定的高度
                this.$refs.pullDownLoading.setText("开始下拉...");
              }else{
                this.$refs.pullDownLoading.setText("向下拉动会重新加载幻灯片哦");
              }
            }else if(swiper.isEnd){//上拉
    
              //是否达到上拉的触发条件
              //swiper的位移加上swiper的高度(617px)-50px的值如果大于当前内容高度
              //swiper.translate这个属性可以获取到wrapper的位移,其实可以理解为滚动条滚动的距离
              //swiper.height这个属性获取swiper容器的高度, 也就是显示区域的高度
              //50px是我们设置的一个值。为了让页面不是到达最低部的时候,可以提前加载内容
              //parseInt(swiper.$wrapperEl.css('height'))是wrapper的HTML元素的height属性, 也就是所有内容的高度
              const isPullUp=Math.abs(swiper.translate)+swiper.height-50 > parseInt(swiper.$wrapperEl.css('height'));
    
              if(isPullUp){//开始上拉
                this.$refs.pullUpLoading.setText("开始上拉");
              }else{//保持初始化
                this.$refs.pullUpLoading.setText('向上拉动会加载更多哦');
              }
            }
          },
          touchEnd(){
    
            if(this.pulling) return;//正在下拉中,则不重复下拉
    
            const swiper=this.$refs.swiper.$swiper;
            
            if(swiper.translate>100){
    
              this.pulling=true;//正在下拉中
    
              swiper.allowTouchMove=false;//禁止触摸
              swiper.setTransition(swiper.params.speed);//设置初始速度
              swiper.setTranslate(100);//移动到设定的位置(拖动过度时回到设置的位置)
              swiper.params.virtualTranslate=true;//定住不给回弹
              this.$refs.pullDownLoading.setText("正在下拉中...");//设置正在刷新中的文字
              this.$emit("pull-down",this.pullDownEnd);//触发消息,传递结束下拉的函数
    
            }else if(swiper.isEnd){//上拉
              //是否达到上拉的触发条件
              const isPullUp=Math.abs(swiper.translate)+swiper.height-30>parseInt(swiper.$wrapperEl.css('height'));
    
              if(isPullUp){//开始上拉
                
                this.pulling=true;
    
                swiper.allowTouchMove=false;//禁止触摸
                swiper.setTransition(swiper.params.speed);//设置初始速度
                swiper.setTranslate(-(parseInt(swiper.$wrapperEl.css('height'))+50-swiper.height));//超过拉动距离时回弹
                swiper.params.virtualTranslate=true;//定住不给回弹
                this.$refs.pullUpLoading.setText("正在上拉中...");//设置正在刷新中的文字
                this.$emit("pull-up",this.pullUpEnd);//触发消息,传递结束下拉的函数
    
              }
            }
          },
          pullDownEnd(){
            const swiper=this.$refs.swiper.$swiper;
    
            this.pulling=false;//下拉结束
    
            this.$refs.pullDownLoading.setText("下拉结束");//设置加载结束后的文字
            swiper.allowTouchMove=true;//可以触摸
            swiper.setTransition(swiper.params.speed);//设置初始速度           
            swiper.params.virtualTranslate=false;//可以回弹
            swiper.setTranslate(0);//移动到最初的位置
    
            //动画完成后再触发结束事件
            setTimeout(()=>{
              this.$emit("pulldown-end");
            },swiper.params.speed);
           
          },
          pullUpEnd(){
            const swiper=this.$refs.swiper.$swiper;
    
            this.pulling=false;
    
            this.$refs.pullUpLoading.setText("上拉结束");//设置加载结束后的文字
            swiper.allowTouchMove=true;//可以触摸           
            swiper.params.virtualTranslate=false;//可以回弹
          },
          scrollTop(){
            this.$refs.swiper.$swiper.slideTo(0);//回到顶部
          },
          scrollEnd(){
            this.$emit("scroll-end",this.$refs.swiper.$swiper.translate,this.$refs.swiper.$swiper,this.pulling);
          }
        }
      }
    </script>
    
    <style lang="scss" scoped>
        .swiper-container{
          100%;
          height:100%;
          overflow:hidden;
        }
        .swiper-slide{
          height:auto;
        }
        .mine-scroll-pull-down{
            position:absolute;
            left:0;
            bottom:100%;
            100%;
            height:80px;
        }
        .mine-scroll-pull-up{
            position:absolute;
            left:0;
            top:100%;
            100%;
            height:30px;
        }
    </style>

    src/pages/home/index.vue

    <template>
        <div class="home">
            <div class="g-header-container">
                <home-header :class="{'header-transition':headerTransition}" ref="header"/>
            </div>
            <scrollbar :data="recommends" @pull-down="pullRefresh" @pull-up="loadMore" @scroll-end="scrollEnd" ref="scroll" @scrolling="changeHeader">
                <slider ref="mySwiper" />
                <home-nav />
                <!-- 热门推荐加载完成后更新滚动条 -->
                <recommend @loaded="updateScroll" ref="recommend" />
            </scrollbar>
            <div class="g-backtop-container">
                <me-backtop :visible="backtopVisible" @backtop="backtop" />
            </div>
            <!-- 该页面自己的子路由 -->
            <router-view></router-view>
        </div>
    
    </template>
    
    <script>
    import Slider from 'components/slider';
    import Scrollbar from 'components/scroll';
    import HomeNav from './nav';
    import Recommend from './recommend';
    import MeBacktop from 'components/backtop';
    import HomeHeader from './header';
    
    export default {
        name:"Home",
        components:{
            Slider,   
            Scrollbar,
            HomeNav,
            Recommend,
            MeBacktop,
            HomeHeader   
        },
        data(){
            return{
                recommends:[],
                backtopVisible:false,
                headerTransition:false
            }
        },
        methods:{
            updateScroll(recommends){
                this.recommends=recommends;
            },
            pullRefresh(end){//刷新轮播图
                this.$refs.mySwiper.getSliders().then(end);
            },
            loadMore(end){//加载更多
                this.$refs.recommend.getRecommends().then(end).catch(err=>{
                    if(err){//没有更多图片了
                        console.log(err);
                    }
                    end();
                });
            },
            scrollEnd(translate,swiper,pulling){//下拉刷新结束
                //显示回到顶部按钮
                this.backtopVisible=translate<0 && -translate>swiper.height;//向下拉并且距离大于一屏
                if(!pulling){
                    this.changeHeader(translate,swiper);
                }
               
            },
            backtop(){
                this.$refs.scroll && this.$refs.scroll.scrollTop();//回到顶部
            },
            changeHeader(translate,swiper){//修改头部导航背景色
                if(translate>0){//下拉中,隐藏导航
                    this.$refs.header.hide();
                    return;
                }else{
                    this.$refs.header.show();
                    this.headerTransition=-translate>200;//大于200时返回true,改变导航背景色
                }
            },
        }
    }
    </script>
    
    <style lang="scss" scoped>
        .home{
            100%;
            height:100%;
        }
        .g-header-container{
            position:absolute;
            left:0;
            top:0;
            100%;
            z-index:999;
            height:50px;
        }
        .g-backtop-container{
            position: absolute;
            z-index:1100;
            right:10px;
            bottom:60px;
        }
    </style>

    src/pages/home/header.vue

    <template>
        <div class="header" v-show="headerVisible">
            <i class="iconfont icon-scan header-left"></i>
            <div class="headerr-center">搜索框</div>
            <i class="iconfont icon-msg header-right"></i>
        </div>
    </template>
    
    <script>
    export default {
        name:"HomeHeader",
        data(){
            return{
               headerVisible:true
            }
        },
        methods:{
            show(){
                this.headerVisible=true;
            },
            hide(){
                this.headerVisible=false;
            }
        }
    }
    </script>
    
    <style lang="scss" scoped>
        .header{
            background:transparent;
            transition:background-color 0.5s;
            display: flex;
            justify-content: space-between;
            align-items: center;
            padding:5px 20px;
    
            .iconfont{
                font-size:24px;
                color:#fff;
            }
    
            //下拉到一定位置,添加.header-transition,使导航背景色变红
            &.header-transition{
                background-color:rgba(222, 24, 27, 0.9);
            } 
    
            .headerr-center{
                flex:1;
            }
        }     
    </style>
  • 相关阅读:
    Block为什么使用Copy?
    iOS运行时,如何增加成员变量
    安卓长按交互onCreateContextMenu的简单 用法
    iOS 检查版本号的代码
    git的基本使用
    svn的使用
    const 关键字及作用
    常见的内存分配
    保存字符串的方法
    指针的总结一(指针的定义)
  • 原文地址:https://www.cnblogs.com/chenyingying0/p/12648477.html
Copyright © 2011-2022 走看看