zoukankan      html  css  js  c++  java
  • vue 上拉刷新组件

      背景,项目中经常会出现需要上拉加载更多或者下拉刷新的需求,一直以来呢都是借用各种UI库来实现,但是不知道啥情况,最近在使用的时候,一直有问题,出不了效果,然人很恼火,于是只能自己动手来实现以下,

      这次做得呢也很简单,只做了上拉加载更多,思路其实很简单,搞一个组件,然后弄个插槽暴露出去放列表,然后在这个组件上监听touchstart,move,end等事件

      我们一般只需要已经滑到最底部了,在上滑才需要判断是否加载更多

      所以我们需要弄清楚几个条件

      1,是否滑动到最底部了,如果是的话,那么在监听到上滑,就计算滑动的距离,如果距离达到了阈值,那么就加载更多

        在处理加载的过程中,一般会给一些文字提示,比如,login中,已经没有更多了,...

      2,如果没有滑动到最底部,那么就是普通的页面滑动,我们不做处理

      大体上就是这些,大部分其他的库会有一些动画效果,我这里没加,具体代码如下:

      

      1 <template>
      2     <div class="pull-wrap" @touchstart="start" @touchmove="move" @touchend="end">
      3     <!--上拉加载组件-->
      4       <slot ref="pull" class="pull-content"></slot>
      5       <p v-if="isMoving" style="font-size: 20px;">pulling....</p>
      6       <div class="is-loading" v-if="isLoading">
      7         <img class="loading" src="../assets/images/loading.svg" alt="">
      8       </div>
      9       <div class="is-done" v-if="isDone">没有数据了</div>
     10   </div>
     11 </template>
     12 
     13 <script>
     14   export default {
     15     name: 'Pull',
     16     props: {
     17       onPull: {  // 上拉的回调
     18         type: Function,
     19         require: true
     20       }
     21 
     22     },
     23     data() {
     24       return {
     25         startY: 0,
     26         moveY: 0,
     27         isMoving: false,
     28         isLoading: false,
     29         isDone: false,
     30         num: 1  // history list的页数
     31       }
     32     },
     33     methods: {
     34       start(e) {
     35         this.startY = e.touches[0].clientY;
     36         console.log(this.startY);
     37       },
     38       move(e) {
     39         if (this.isDone) return
     40         console.log('move', e.touches[0].clientY);
     41         // 滑动时需要检测是否到底了,如果还没到底,就不要loading
     42         // if (this.isLoading || this.isDone) return;
     43         let flag = this.scrollToTheEnd();
     44         if (flag) {
     45           this.isMoving = true
     46         }
     47         this.moveY = e.touches[0].clientY - this.startY;
     48       },
     49 
     50       end() {
     51         // this.isMoving = false
     52         if (this.isLoading || this.isDone) return;
     53         console.log('touchend', this.moveY);
     54         if (this.moveY > -40) {
     55           console.log('没超过', this.moveY);
     56           this.isMoving = false;
     57         } else {
     58           console.log('达到条件了');
     59           let flag = this.scrollToTheEnd();
     60           console.log(flag, '到底了吗');
     61           if (!flag) return;
     62           this.isMoving = false
     63           this.num++;
     64           this.isLoading = true;
     65           this.onPull(this.num);
     66         }
     67         this.startY = 0;
     68         this.moveY = 0;
     69       },
     70 
     71       /**
     72        * 判断滚动条是否到底
     73        */
     74       scrollToTheEnd() {
     75         let scrollTop = document.documentElement.scrollTop || window.pageYOffset || document.body.scrollTop // 滚动的距离
     76         let viewHeight = document.documentElement.clientHeight;  // 可视区域高度
     77         let offsetHeight = document.body.scrollHeight;  // 总高度
     78         console.log(scrollTop, viewHeight, offsetHeight, '----------------');
     79         // 滚动条到底部的条件
     80         return (viewHeight + scrollTop) >= offsetHeight
     81       }
     82     },
     83 
     84     mounted() {
     85       this.$on('loadEnd', () => {
     86         console.log('load完毕了');
     87         this.isLoading = false
     88       })
     89 
     90       this.$on('loadOver', () => {
     91         console.log('没有了');
     92         this.isDone = true;
     93         this.isLoading = false;
     94         this.isMoving = false;
     95       })
     96 
     97     }
     98   }
     99 </script>
    100 
    101 <style scoped lang="scss">
    102   /*.pull-wrap{
    103     overflow: hidden;
    104     &>.pull-content{
    105      transition: all .4s;
    106    }
    107   }*/
    108   .pull-wrap{
    109     font-size: 20px;
    110   }
    111 
    112   .loading{
    113      50px;
    114     height: 50px;
    115   }
    116 
    117 </style>

    然后使用组件的如下:

    <template>
      <Pull :onPull="pull" ref="pull">
              <p v-for="val in list">列表了{{val}}</p>p
        </Pull>
    </template>  
    
    <script>
    import Pull from '../Pull'
    methods:{
    
    //这里就是加载更多的处理函数了,这里只是用定时器模拟了一下,需要将加载状态回传到子组件中去
     pull(num) {
            console.log('pull回调');
            setTimeout(() => {
              this.num = num;
              if (this.history_list.length >= this.pk_list_data.others_family_list.length) {
                console.log('完了');
                this.$refs.pull.$emit('loadOver') // 加载完毕
              } else {
                this.$refs.pull.$emit('loadEnd') // 加载完毕
              }
    
            }, 2000)
    
          },
    
    }
    
    </script> 

    这样,基本就做完了,

  • 相关阅读:
    常见的排序算法(四):归并排序
    常见的排序算法(三):快速排序
    常见的排序算法(二):选择排序
    a标签没有闭合引起自动插入很多a标签的问题
    js笔记
    Vue笔记
    CSS笔记
    bootstrap--网格化布局
    backgroud图片充满元素的方法
    bootstrap--概述
  • 原文地址:https://www.cnblogs.com/ysla/p/11826826.html
Copyright © 2011-2022 走看看