在作移動端的避免不了 下拉刷新,上拉加載css
直接上代碼吧,哈哈html
組件裏:vue
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>
而後web
把上面組件拷貝一下,保存vue文件refresh.vue放到你的component/common文件夾下, 而後引入到頁面 , api
下面是引用個人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>
好啦 看下效果圖app