目前有很多方式可以實作上拉重新整理下拉加載的功能
基于vue2.0并參考網上的一些執行個體完善了一個vue的元件來實作上拉重新整理,下拉下載下傳的功能。
下拉重新整理

下拉加載更多
暫無資料
以下為代碼
scroll.vue檔案
template部分
script部分
export default {
props: {
offset: {
type: Number,
default: 40 // 預設高度
},
enableInfinite: {
type: Boolean,
default: true
enableRefresh: {
dataList: {
default: false,
required: false
onRefresh: {
type: Function,
default: undefined,
onInfinite: {
require: false
}
},
data () {
return {
top: 0,
state: 0,
startX: 0,
startY: 0,
touching: false,
infiniteLoading: false,
downFlag: true // 用來顯示是否加載中
methods: {
touchStart (e) {
this.startY = e.targetTouches[0].pageY
this.startX = e.targetTouches[0].pageX
this.startScroll = this.$el.scrollTop || 0
this.touching = true // 留着有用,不能删除
this.dataList.noFlag = false
this.$el.querySelector('.load-more').style.display = 'block'
touchMove (e) {
if (!this.enableRefresh || this.dataList.noFlag || !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
if (this.top >= this.offset) {
this.state = 1
} else {
this.state = 0
let more = this.$el.querySelector('.load-more')
if (!this.top && this.state === 0) {
more.style.display = 'block'
more.style.display = 'none'
touchEnd (e) {
if (!this.enableRefresh) {
this.touching = false
this.state = 2
this.top = this.offset
if (this.top >= this.offset) { // do refresh
this.refresh()
} else { // cancel refresh
this.top = 0
// 用于判斷滑動是否在原地 ----begin
let endX = e.changedTouches[0].pageX
let endY = e.changedTouches[0].pageY
let dy = this.startY - endY
let dx = endX - this.startX
// 如果滑動距離太短
if (Math.abs(dx) < 2 && Math.abs(dy) < 2) {
// console.log('滑動距離太短')
// --------end--------
if (!this.enableInfinite || this.infiniteLoading) {
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 bottom = innerHeight - outerHeight - scrollTop - ptrHeight
// console.log(bottom + '__' + this.offset)
if (bottom <= this.offset && this.state === 0) {
this.downFlag = true
this.infinite()
this.$el.querySelector('.load-more').style.display = 'none'
this.downFlag = false
onScroll (e) {
if (!this.enableInfinite) {
let outerHeight = this.$el.clientHeight // 螢幕内容區域 316
let innerHeight = this.$el.querySelector('.inner').clientHeight // inner height 923
let scrollTop = this.$el.scrollTop // 滾動條距頂部高度
let ptrHeight = this.onRefresh ? this.$el.querySelector('.pull-refresh').clientHeight : 0 // 下拉重新整理div高度
let infiniteHeight = this.$el.querySelector('.load-more').clientHeight // 上拉加載更多div高度
if (bottom + infiniteHeight - 1 <= infiniteHeight) {
refresh () {
this.state = 2
this.top = this.offset
setTimeout(() => {
this.onRefresh(this.refreshDone)
}, 300)
refreshDone () {
this.state = 0
this.top = 0
infinite () {
this.infiniteLoading = true
this.onInfinite(this.infiniteDone)
}, 2000)
infiniteDone () {
this.infiniteLoading = false
}
}
style部分
.yo-scroll {
position: absolute;
top: 2.78rem;
right: 0;
bottom: 0;
left: 0;
overflow: auto;
-webkit-overflow-scrolling: touch;
background-color: #fff
.yo-scroll .inner {
top: -2rem;
width: 93%;
transition-duration: 300ms;
padding: 0 .25rem;
.yo-scroll .pull-refresh {
position: relative;
top: 0;
width: 100%;
height: 2rem;
display: flex;
align-items: center;
justify-content: center;
font-size:.3rem;
.yo-scroll.touch .inner {
transition-duration: 0ms;
.yo-scroll.down .down-tip {
display: block;
.yo-scroll.up .up-tip {
.yo-scroll.refresh .refresh-tip {
.yo-scroll .down-tip,
.yo-scroll .refresh-tip,
.yo-scroll .up-tip {
display: none;
.yo-scroll .load-more {
height: 1.5rem;
text-align: center;
line-height: 1.5rem;
.nullData{
font-size: .3rem;
height: 1rem;
line-height: 1rem;
以下為使用方法
template 部分
import scroll from '../scroll'
export default {
data() {
return {
counter: 1, //目前頁
num: 10, // 一頁顯示多少條
pageStart: 0, // 開始頁數
pageEnd: 0, // 結束頁數
listdata: [], // 下拉更新資料存放數組
scrollData: {
noFlag: false //暫無更多資料顯示
}
}
},
components: {
'v-scroll':scroll
mounted: function() {
this.getList();
methods: {
getList() {
var response = []
for(let i = 0; i < 20; i++) {
response.push({
date: "2017-06-1"+i,
portfolio: "1.5195"+i,
drop: i+"+.00 %" ,
state: 1
})
this.listdata = response.slice(0, this.num);
},
onRefresh(done) {
this.getList();
done(); // call done
onInfinite(done) {
this.counter++;
let end = this.pageEnd = this.num * this.counter;
let i = this.pageStart = this.pageEnd - this.num;
let more = this.$el.querySelector('.load-more')
for(i; i < end; i++) {
if(i >= 30) {
more.style.display = 'none'; //隐藏加載條
//走完資料調用方法
this.scrollData.noFlag = true;
break;
} else {
this.listdata.push({
date: "2017-06-1"+i,
portfolio: "1.5195"+i,
drop: i+"+.00 %" ,
state: 2
})
}
done();
}