vue2.0 移动端,下拉刷新,上拉加载更多 封装组件

前言

在做移动端的避免不了 下拉刷新,上拉加载

直接上代码吧,哈哈

组件里:

  1 <template lang="html">
  2   <div class="yo-scroll"
  3   :class="{'down':(state===0),'up':(state==1),refresh:(state===2),touch:touching}"
  4   @touchstart="touchStart($event)"
  5   @touchmove="touchMove($event)"
  6   @touchend="touchEnd($event)"
  7   @scroll="(onInfinite || infiniteLoading) ? onScroll($event) : undefined">
  8     <section class="inner" :style="{ transform: 'translate3d(0, ' + top + 'px, 0)' }">
  9       <header class="pull-refresh">
 10         <slot name="pull-refresh">
 11            <span class="down-tip">下拉更新</span>
 12            <span class="up-tip">松开更新</span>
 13            <span class="refresh-tip">更新中……</span>
 14         </slot>
 15       </header>
 16       <slot></slot>
 17       <footer class="load-more">
 18         <slot name="load-more">
 19           <span>{{loadingText}}</span>
 20         </slot>
 21       </footer>
 22     </section>
 23   </div>
 24 </template>
 25  
 26 <script>
 27 export default {
 28   name: 'kl-scroll',
 29   props: {
 30     offset: {
 31       type: Number,
 32       default: 40
 33     },
 34     loadingText: {
 35       type: String,
 36       default: '加载中...'
 37     },
 38     enableInfinite: {
 39       type: Boolean,
 40       default: true
 41     },
 42     enableRefresh: {
 43       type: Boolean,
 44       default: true
 45     },
 46     onRefresh: {
 47       type: Function,
 48       default: undefined,
 49       required: false
 50     },
 51     onInfinite: {
 52       type: Function,
 53       default: undefined,
 54       require: false
 55     }
 56   },
 57   data() {
 58     return {
 59       top: 0,
 60       state: 0,
 61       startY: 0,
 62       touching: false,
 63       infiniteLoading: false
 64     }
 65   },
 66   methods: {
 67     touchStart(e) {
 68       this.startY = e.targetTouches[0].pageY
 69       this.startScroll = this.$el.scrollTop || 0
 70       this.touching = true
 71     },
 72     touchMove(e) {
 73       if (!this.enableRefresh || this.$el.scrollTop > 0 || !this.touching) {
 74         return
 75       }
 76       let diff = e.targetTouches[0].pageY - this.startY - this.startScroll
 77       if (diff > 0) e.preventDefault()
 78       this.top = Math.pow(diff, 0.8) + (this.state === 2 ? this.offset : 0)
 79  
 80       if (this.state === 2) { // in refreshing
 81         return
 82       }
 83       if (this.top >= this.offset) {
 84         this.state = 1
 85       } else {
 86         this.state = 0
 87       }
 88     },
 89     touchEnd(e) {
 90       if (!this.enableRefresh) return
 91       this.touching = false
 92       if (this.state === 2) { // in refreshing
 93         this.state = 2
 94         this.top = this.offset
 95         return
 96       }
 97       if (this.top >= this.offset) { // do refresh
 98         this.refresh()
 99       } else { // cancel refresh
100         this.state = 0
101         this.top = 0
102       }
103     },
104     refresh() {
105       this.state = 2
106       this.top = this.offset
107       this.onRefresh(this.refreshDone)
108     },
109     refreshDone() {
110       this.state = 0
111       this.top = 0
112       this.infiniteLoading = false
113     },
114  
115     infinite() {
116       this.infiniteLoading = true
117       this.onInfinite(this.infiniteDone)
118     },
119  
120     infiniteDone() {
121       this.infiniteLoading = false
122     },
123  
124     onScroll(e) {
125       if (!this.enableInfinite || this.infiniteLoading) {
126         return
127       }
128       let outerHeight = this.$el.clientHeight
129       let innerHeight = this.$el.querySelector('.inner').clientHeight
130       let scrollTop = this.$el.scrollTop
131       let ptrHeight = this.onRefresh ? this.$el.querySelector('.pull-refresh').clientHeight : 0
132       let infiniteHeight = this.$el.querySelector('.load-more').clientHeight
133       let bottom = innerHeight - outerHeight - scrollTop - ptrHeight
134       if (bottom < infiniteHeight) this.infinite()
135     }
136   }
137 }
138 </script>
139 <style >
140 .yo-scroll {
141   position: absolute;
142   /* top: 2.5rem;  */
143    top: 0;
144   right: 0;
145   bottom: 0;
146   left: 0;
147   overflow: auto;
148   -webkit-overflow-scrolling: touch;
149   background-color: #f5f8fa;
150 }
151 .yo-scroll .inner {
152   position: absolute;
153   top: -2rem;
154   width: 100%;
155   transition-duration: 300ms;
156 }
157 .yo-scroll .pull-refresh {
158   position: relative;
159   left: 0;
160   top: 0;
161   width: 100%;
162   height: 2rem;
163   display: flex;
164   align-items: center;
165   justify-content: center;
166 }
167 .yo-scroll.touch .inner {
168   transition-duration: 0ms;
169 }
170 .yo-scroll.down .down-tip {
171   display: block;
172 }
173 .yo-scroll.up .up-tip {
174   display: block;
175 }
176 .yo-scroll.refresh .refresh-tip {
177   display: block;
178 }
179 .yo-scroll .down-tip,
180 .yo-scroll .refresh-tip,
181 .yo-scroll .up-tip {
182   display: none;
183 }
184 .yo-scroll .load-more {
185   height: 1rem;
186   display: flex;
187   align-items: center;
188   justify-content: center;
189 }
190 </style>
View Code

然后

把上面组件拷贝一下,保存vue文件refresh.vue放到你的component/common文件夹下,  然后引入到页面 ,

下面是引用我的demo

<template>
  <kl-scroll :on-refresh="onRefresh" :on-infinite="onInfinite" :loading-text="loadingText">
    <section class="app-body container">
      <div class="container top30r record-table">
        <div class="record-header">
          <span class="label-time">提款时间</span>
          <span class="label-withdraw-amount">提现金额</span>
          <span class="label-arrival-amount">到帐金额</span>
          <span class="label-status">到账状态</span>
        </div>
        <div class="record-body">
          <div class="record-body-row" v-for="(item,index) in records" :key="index">
            <span class="time">{{item._created_at}}</span>
            <span class="withdraw-amount">{{item.withdraw_amount}}</span>
            <span class="arrival-amount">{{item.arrival_amount}}</span>
            <span
              class="status"
              :class="item.status == withdrawStatus.arrival ? 'label-green' : ''"
            >{{item._status}}</span>
          </div>
        </div>
      </div>
    </section>
  </kl-scroll>
</template>

<script>
import api from "@/api";
import qs from "qs";
export default {
  name: "withdrawRecord",
  data() {
    return {
      withdrawStatus: {
        arrival: 1
      },
      records: [
        // {
        //   _created_at: "2019-03-07 15:20",
        //   withdraw_amount: "137854",
        //   arrival_amount: "13552.55",
        //   status: 1
        // }
      ],
      loadingText: "加载中...",
      page: 0, //当前页面
      num: 20, // 一次显示多少条
      listdata: [], // 下拉更新数据存放数组
      downdata: [] // 上拉更多的数据存放数组
    };
  },
  beforeCreate() {
    this.$loading.open();
  },
  mounted() {
    let vm = this;
    this.$nextTick(() => {
      vm.getList();
    });
  },
  methods: {
    onRefresh(done) {
      let _this = this;
      _this.counter = 1;
      _this.$el.querySelector(".load-more").style.display = "flex";
      _this.loadingText = "加载中……";
      _this.getList();
      done(); // call done
    },
    onInfinite(done) {
      let _this = this;
      let arr = [];
      for (var i = 0; i < 10; i++) {
        arr.push({
          _created_at: "2019-03-07 15:20",
          withdraw_amount: 155 + i,
          arrival_amount: "13552.55",
          status: 1,
          _status: "到賬"
        });
      }
      setTimeout(() => {
        _this.records = _this.records.concat(arr);
      }, 300);

      if (arr.length < _this.num) {
        _this.loadingText = "加载完毕……";
        //vm.$el.querySelector('.load-more').style.display = 'none';
        return;
      } else {
        _this.counter++;
      }
      done(); // call done
    },
    getList() {
      let _this = this;
      // let arr = [];
      // for (var i = 0; i < 40; i++) {
      //   arr.push({
      //     _created_at: "2019-03-07 15:20",
      //     withdraw_amount: 155 + i,
      //     arrival_amount: "13552.55",
      //     status: 1,
      //     _status: "到賬"
      //   });
      // }

      // _this.records = arr;
      // if (arr.length >= _this.num) {
      //   _this.counter++;
      // }
      let urlParams = {
        urlParams: {
          page: _this.page
        }
      };
      api.withdrawRecords(urlParams).then(res => {
        if (res.data) {
          let data = res.data.data;
          _this.records = data.records;
          if (_this.records.length == 0 || _this.records.length < _this.num) {
            _this.loadingText = "加载完毕……";
            _this.$el.querySelector(".load-more").style.display = "none";
          }
          _this.$loading.close();
        }
      });
    }
  }
};
</script>

<style lang="scss" scoped>

好啦 看下效果图

 

猜你喜欢

转载自www.cnblogs.com/yf-html/p/10553877.html