美文网首页
vue2 下拉刷新,上拉加载更多 组件封装

vue2 下拉刷新,上拉加载更多 组件封装

作者: Q_骑猪看夕阳 | 来源:发表于2018-12-24 17:24 被阅读0次

    本人正在基于 vue2.0 + webpack + es6 搭建前端架构,整理了部分插件,下面这个是下拉更新 上拉更多的,挺好用的,分享给大家。
    直接上代码,不懂的多看几遍,下面我换会告诉大家如何使用。

      <div class="yo-scroll"
      :class="{'down':(state===0),'up':(state==1),refresh:(state===2),touch:touching}"
      @touchstart="touchStart($event)"
      @touchmove="touchMove($event)"
      @touchend="touchEnd($event)"
      @scroll="(onInfinite || infiniteLoading) ? onScroll($event) : undefined">
        <section class="inner" :style="{ transform: 'translate3d(0, ' + top + 'px, 0)' }">
          <header class="pull-refresh">
            <slot name="pull-refresh">
               <span class="down-tip">下拉更新</span>
               <span class="up-tip">松开更新</span>
               <span class="refresh-tip">更新中</span>
            </slot>
          </header>
          <slot></slot>
          <footer class="load-more">
            <slot name="load-more">
              <span>加载中……</span>
            </slot>
          </footer>
        </section>
      </div>
    </template>
    
    <script>
    export default {
      props: {
        offset: {
          type: Number,
          default: 40
        },
        enableInfinite: {
          type: Boolean,
          default: true
        },
        enableRefresh: {
          type: Boolean,
          default: true
        },
        onRefresh: {
          type: Function,
          default: undefined,
          required: false
        },
        onInfinite: {
          type: Function,
          default: undefined,
          require: false
        }
      },
      data() {
        return {
          top: 0,
          state: 0,
          startY: 0,
          touching: false,
          infiniteLoading: false
        }
      },
      methods: {
        touchStart(e) {
          this.startY = e.targetTouches[0].pageY
          this.startScroll = this.$el.scrollTop || 0
          this.touching = true
        },
        touchMove(e) {
          if (!this.enableRefresh || this.$el.scrollTop > 0 || !this.touching) {
            return
          }
          let diff = e.targetTouches[0].pageY - this.startY - this.startScroll
          if (diff > 0) e.preventDefault()
          this.top = Math.pow(diff, 0.8) + (this.state === 2 ? this.offset : 0)
    
          if (this.state === 2) { // in refreshing
            return
          }
          if (this.top >= this.offset) {
            this.state = 1
          } else {
            this.state = 0
          }
        },
        touchEnd(e) {
          if (!this.enableRefresh) return
          this.touching = false
          if (this.state === 2) { // in refreshing
            this.state = 2
            this.top = this.offset
            return
          }
          if (this.top >= this.offset) { // do refresh
            this.refresh()
          } else { // cancel refresh
            this.state = 0
            this.top = 0
          }
        },
        refresh() {
          this.state = 2
          this.top = this.offset
          this.onRefresh(this.refreshDone)
        },
        refreshDone() {
          this.state = 0
          this.top = 0
        },
    
        infinite() {
          this.infiniteLoading = true
          this.onInfinite(this.infiniteDone)
        },
    
        infiniteDone() {
          this.infiniteLoading = false
        },
    
        onScroll(e) {
          if (!this.enableInfinite || this.infiniteLoading) {
            return
          }
          let outerHeight = this.$el.clientHeight
          let innerHeight = this.$el.querySelector('.inner').clientHeight
          let scrollTop = this.$el.scrollTop
          let ptrHeight = this.onRefresh ? this.$el.querySelector('.pull-refresh').clientHeight : 0
          let infiniteHeight = this.$el.querySelector('.load-more').clientHeight
          let bottom = innerHeight - outerHeight - scrollTop - ptrHeight
          if (bottom < infiniteHeight) this.infinite()
        }
      }
    }
    </script>
    <style>
    .yo-scroll {
      position: absolute;
      top: 2.5rem;
      right: 0;
      bottom: 0;
      left: 0;
      overflow: auto;
      -webkit-overflow-scrolling: touch;
      background-color: #ddd
    }
    .yo-scroll .inner {
      position: absolute;
      top: -2rem;
      width: 100%;
      transition-duration: 300ms;
    }
    .yo-scroll .pull-refresh {
      position: relative;
      left: 0;
      top: 0;
      width: 100%;
      height: 2rem;
      display: flex;
      align-items: center;
      justify-content: center;
    }
    .yo-scroll.touch .inner {
      transition-duration: 0ms;
    }
    .yo-scroll.down .down-tip {
      display: block;
    }
    .yo-scroll.up .up-tip {
      display: block;
    }
    .yo-scroll.refresh .refresh-tip {
      display: block;
    }
    .yo-scroll .down-tip,
    .yo-scroll .refresh-tip,
    .yo-scroll .up-tip {
      display: none;
    }
    .yo-scroll .load-more {
      height: 3rem;
      display: flex;
      align-items: center;
      justify-content: center;
    }  
    </style>```
    把上面组件拷贝一下,存成后缀是.vue的组件放到你的component下,  然后引入到页面 , 下面是我引用的demo
    
    上代码: 里面有注释哦,有问题给我留言!
    
    ```代码块```
    ```<template>
      <div>
           <v-scroll :on-refresh="onRefresh" :on-infinite="onInfinite">
           <ul>
             <li v-for="(item,index) in listdata" >{{item.name}}</li>
             <li v-for="(item,index) in downdata" >{{item.name}}</li>
           </ul>
        </v-scroll>
      </div>
    </template>
    <script>
    import Scroll from './y-scroll/scroll';
    
    export default{
     data () {
        return {
          counter : 1, //默认已经显示出15条数据 count等于一是让从16条开始加载
          num : 15,  // 一次显示多少条
          pageStart : 0, // 开始页数
          pageEnd : 0, // 结束页数
          listdata: [], // 下拉更新数据存放数组
          downdata: []  // 上拉更多的数据存放数组
        }
      },
      mounted : function(){
         this.getList();
      },
      methods: {
        getList(){
           let vm = this;
              vm.$http.get('https://api.github.com/repos/typecho-fans/plugins/contents/').then((response) => {
                       vm.listdata = response.data.slice(0,15);
                     }, (response) => {
                        console.log('error');
                    });
        },
        onRefresh(done) {
                 this.getList();
           
                 done() // call done
          
        },
        onInfinite(done) {
                  let vm = this;
                  vm.$http.get('https://api.github.com/repos/typecho-fans/plugins/contents/').then((response) => {
                      vm.counter++;
                      vm.pageEnd = vm.num * vm.counter;
                      vm.pageStart = vm.pageEnd - vm.num;
                      let arr = response.data;
                         let i = vm.pageStart;
                         let end = vm.pageEnd;
                         for(; i<end; i++){
                            let obj ={};
                            obj["name"] = arr[i].name;
                            vm.downdata.push(obj);
                             if((i + 1) >= response.data.length){
                              this.$el.querySelector('.load-more').style.display = 'none';
                              return;
                            }
                            }
                      done() // call done
                       }, (response) => {
                        console.log('error');
                    });
               }
      },
      components : {
    'v-scroll': Scroll
      }
    }
    </script>```

    相关文章

      网友评论

          本文标题:vue2 下拉刷新,上拉加载更多 组件封装

          本文链接:https://www.haomeiwen.com/subject/yzwzkqtx.html