本项目是用vue +elementui来写移动端 的:
首先创建一个每个需要上拉加载数据的模板组件 LoadMore.vue
<template>
<div id="LoadMore" class="clearfix">
<div class="load-more-wrapper clearfix">
<div class="load-refresh refresh" v-show="isRefresh">
{{refreshText}}
<i class="el-icon-bottom"></i>
</div>
<div
class="inner"
@touchstart="touchStart($event)"
@touchend="touchEnd($event)"
>
<slot></slot>
<div class="load-more" v-show="enableLoadMore">
{{loadMoreText}}
<i class="el-icon-top"></i>
</div>
<div class="load-end" v-show="!enableLoadMore">已经到底了!</div>
</div>
</div>
</div>
</template>
<script>
export default {
name: "LoadMore",
props: {
enableLoadMore: {
type: Boolean,
default: true
},
onLoadMore: {
type: Function,
default: undefined,
require: false
}
},
data() {
return {
isRefresh: false,
refreshText: "下拉刷新",
loadMoreText: "上拉加载更多",
startX: 0,
startY: 0,
isLoading: false,
top: 0,
touching: false,
scrollTop: 0,
loading:""
};
},
methods: {
openFullScreen() {//设置弹出框
this.loading = this.$loading({
lock: true,
text: 'Loading',
spinner: 'el-icon-loading',
background: 'rgba(0, 0, 0, 0.7)'
});
},
onEnlargeText: function(enlargeAmount) {},
touchStart(e) {
this.startY = e.targetTouches[0].pageY;
this.startX = e.targetTouches[0].pageX;
},
closeloading(){
this.loading.close();
},
scrollToEnd(e) {
let windowHeight = window.screen.height;
let scrollHeight = this.$el.scrollHeight;
let clientHeight = this.$el.clientHeight;
this.scrollTop =
document.documentElement.scrollTop || document.body.scrollTop;
if (this.scrollTop == 0 && this.touching) {
this.isRefresh = false;
this.doLoadMore("total");// 下拉刷新
}
if (this.touching) {
// 下拉动作不加载下一页
return false;
}
if (!this.enableLoadMore) {
this.$message({
showClose: true,
message: "没有更多数据了!",
type: "error",
center: true
});
} else if (
scrollHeight > windowHeight &&
this.scrollTop + windowHeight >= scrollHeight &&
this.scrollTop + clientHeight >= scrollHeight
) {
this.doLoadMore();
this.loading
} else if (
scrollHeight < windowHeight &&
this.scrollTop + clientHeight >= scrollHeight
) {
this.doLoadMore();
}
},
touchEnd(e) {
if (this.isLoading) {
return;
}
let endX = e.changedTouches[0].pageX,
endY = e.changedTouches[0].pageY,
dy = this.startY - endY,
dx = endX - this.startX;
if (Math.abs(dx) < 2 && Math.abs(dy) < 2) {
return;
}
if (endY < this.startY) {
this.touching = false; // 上滑
this.scrollToEnd(e);
} else if (endY > this.startY) {
this.touching = true; // 下拉
this.scrollToEnd(e);
}
this.isRefresh = true;
},
doLoadMore(total = "") {
this.isLoading = true;
this.loadMoreText = "加载中...";
this.openFullScreen();//显示遮罩层
this.onLoadMore(this.loadDone, total);
},
loadDone() {
this.isLoading = false;
this.loadMoreText = "上拉加载更多";
}
}
};
</script>
<style lang="less" scoped>
#LoadMore{
.load-more-wrapper {
height: 100%;
overflow-y: auto;
-webkit-overflow-scrolling: touch;
transition-duration: 300ms;
.inner {
width: 100%;
height: 100%;
.load-refresh,
.load-more,
.load-end {
color: #aea699;
font-size: 1rem;
margin: 0.3rem 0;
text-align: center;
}
}
.refresh {
position: absolute;
top: 44px;
left: 44%;
z-index: 9;
color: #aea699;
font-size:.75rem;
text-align: center;
}
}
}
</style>
然后在父页面引入子组件LoadMore.vue
<template>
<div id="classSchedule" class="clearfix">
<div class="main clearfix">
<div class="main-page-wrapper clearfix">
<LoadMore :onLoadMore="onLoadMore" :enableLoadMore="enableLoadMore" ref="LoadMore">
<!-- 表格 -->
<div class="contents">
<el-row type="flex" class="row-bg header_fidx" :span="24">
<el-col :span="8" class="col_row1">
<a class="grid-content rows">班级名称</a>
</el-col>
<el-col :span="8" class="col_row1">
<a class="grid-content">所在年级</a>
</el-col>
<el-col :span="8" class="col_row2">
<a class="grid-content">详情</a>
</el-col>
</el-row>
<el-row
type="flex"
class="row-bg"
:span="24"
v-for="(item,index) in tableData"
:key="index"
>
<el-col :span="8" class="col_row1">
<a class="grid-content rows">{{item.className}}</a>
</el-col>
<el-col :span="8" class="col_row1">
<a class="grid-content">{{item.gradeName}}</a>
</el-col>
<el-col :span="8" class="col_row2">
<div @click="getmsg(item) ">
<i class="el-icon-arrow-right grid-content"></i>
</div>
</el-col>
</el-row>
</div>
</LoadMore>
</div>
</div>
</div>
</template>
<script>
import LoadMore from "@/components/LoadMore.vue";
export default {
name: "classSchedule",
components: {
LoadMore
},
data() {
return {
tableData: [],
page: 1,
enableLoadMore: true,
isRefresh: false,
lastPage: ""
};
},
created() {
this.Schedulle();
},
methods: {
//初始页面数据渲染
async Schedulle() {
let res = await this.$api.CLASS_SCHEDULE("");
if (res.data.errcode == 0) {
this.tableData = res.data.items;
this.lastPage = res.data.lastPage;
} else {
this.$message({
showClose: true,
message: "错了哦,获取数据失败!",
type: "error",
center: true
});
console.log(error);
}
},
//下拉加载数据
onLoadMore(done, total = "") {
setTimeout(() => {
if (!this.enableLoadMore) {
return;
}
if (total == "") {
this.page = this.page + 1;
}
this.getListData(total);
done();
}, 200);
},
getListData(total = "") {
if (this.page <= this.lastPage) {
this.$api
.CLASS_SCHEDULE("page=" + this.page + "&total=" + total+"&gradeId=" + this.chindId + "")
.then(res => {
this.$refs.LoadMore.closeloading(); // 取消遮罩层
if (res.data.errcode != 0) {
this.$message({
showClose: true,
message: "没有更多数据了!",
type: "error",
center: true
});
// this.enableLoadMore = false;
return false;
}
if (total == "") {
this.tableData = this.tableData.concat(res.data.items);
} else {
this.tableData = res.data.items;
}
});
} else {
this.$message({
showClose: true,
message: "没有更多数据了!",
type: "error",
center: true
});
this.$refs.LoadMore.closeloading(); // 取消遮罩层
}
}
}
};
</script>
<style lang="less">
@import "../../assets/CSS/less/form.less";
</style>
如有相似页面的话,也可把需要你上拉加载数据的部分分成一个组件引入