• 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);//移动到最初的位置
    
            this.$emit("pulldown-end");
            
          },
          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);
          }
        }
      }
    </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>

    scr/components/backtop/index.vue

    <template>
        <transition name="mine-backtop">
            <a href="javascript:;" class="mine-backtop" v-show="visible" @click="backToTop">
                <i class="iconfont icon-backtop"></i>
            </a>
        </transition>
    </template>
    
    <script>
    export default {
        name:"MeBacktop",
        props:{
           visible:{
               type:Boolean,
               default:false
           } 
        },
        methods:{
            backToTop(){
                this.$emit("backtop");//基础组件,与业务无关,具体实现去页面里
            }
        }
    }
    </script>
    
    <style lang="scss" scoped>
    
        .mine-backtop{
            overflow:hidden;
            display: flex;
            justify-content: center;
            align-items: center;
            flex-direction:row;
            45px;
            height:45px;
            background:rgba(0,0,0,.6);
            border:none;
            border-radius:50%;
        }
        .iconfont{
           color:#fff;
           font-size:38px; 
        }
        .mine-backtop{
            &-enter-active,
            &-leave-active{
                transition:opacity 0.4s;
            }
            &-enter,
            &-leave-to{
                opacity:0;
            }
        }
    </style>

    src/pages/home/index.vue

    <template>
        <div class="home">
            <scrollbar :data="recommends" @pull-down="pullRefresh" @pull-up="loadMore" @scroll-end="scrollEnd" ref="scroll">
                <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';
    
    export default {
        name:"Home",
        components:{
            Slider,   
            Scrollbar,
            HomeNav,
            Recommend,
            MeBacktop    
        },
        data(){
            return{
                recommends:[],
                backtopVisible: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){//下拉刷新结束
                //显示回到顶部按钮
                this.backtopVisible=translate<0 && -translate>swiper.height;//向下拉并且距离大于一屏
            },
            backtop(){
                this.$refs.scroll && this.$refs.scroll.scrollTop();//回到顶部
            }
        }
    }
    </script>
    
    <style lang="scss" scoped>
        .home{
            100%;
            height:100%;
        }
        .g-backtop-container{
            position: absolute;
            z-index:1100;
            right:10px;
            bottom:60px;
        }
    </style>
  • 相关阅读:
    HDU 3547 DIY Cube
    POJ 2975 Nim
    POJ 1678 I Love this Game!
    POJ 2234 Matches Game
    POJ 3537 Crosses and Crosses
    POJ 3710 Christmas Game
    POJ 1704 Georgia and Bob
    HDU 3923 Invoker
    POJ 2154 Color
    PLM更新自定义CLASS
  • 原文地址:https://www.cnblogs.com/chenyingying0/p/12644139.html
Copyright © 2020-2023  润新知