在当前列表有很多数据的时候,我们一般会采用分页加载数据,这里我们也可以通过滚动加载更多数据。
在这里我们先要知道滚动到什么时候,开始请求数据。
外层盒子设置overflow:auto
内层盒子高度不定。
超出外层盒子滚动。
当内部盒子滚动到距离外部盒子底部50px的时候开始加载数据。
页面布局
<div class="history-list-box scroll-bar" ref="scrollBox">
<ul class="history-list" id="history-list" v-if="historySubList.length > 0">
<li v-for="(h, k) in historySubList" :key="k">
<div class="history-item">
<div v-if="h.state === '1'" class="sub-flag-box">
<img src="../../assets/img/myReport/dy.png" alt="sub-icon">
<p>已订阅</p>
</div>
<div v-else-if="h.state === '0'" class="sub-flag-box">
<img src="../../assets/img/myReport/cancel.png" alt="sub-cancel-icon">
<p>取消订阅</p>
</div>
<div class="sub-desc" :class="{'sub-cancel': h.state === '0'}">
<p class="sub-tit">{{h.topicName}}</p>
<p class="sub-topic">{{h.themeName}}</p>
<p class="sub-date">{{h.createTime}}</p>
</div>
</div>
<div class="baseline"></div>
</li>
</ul>
<p v-else style="margin-top: .5rem; font-size: .16rem; color: #ffffff">暂无历史订阅记录</p>
</div>
业务逻辑代码
export default {
data(){
return {
// 滚动分页
pageInfo: {
page: 1,
limit: 10
},
// 是否进行滚动加载
pageFlag: true,
// 返回的数据
historySubList: [],
// 计步器
limitWatcher: 1
}
},
mounted() {
// 监听外部盒子的滚动事件
this.$refs.scrollBox.addEventListener('scroll', this.handleScroll)
},
methods: {
// 获取接口数据
getHistoryListData (type = '') {
let jsonData = {
data: type,
pageInfo: {
page: this.pageInfo.page,
limit: this.pageInfo.limit
}
}
topicReport.myReport.historySubListData(jsonData).then((res) => {
if (res.code === 0) {
this.historySubList = res.data
// 关键代码 根据是否大于后台返回的数据总数,来决定是否继续滚动加载
this.pageFlag = this.pageInfo.limit <= res.totalNum
}
})
},
// 监听滚动
handleScroll () {
let outerClientHeight = this.$refs.scrollBox.clientHeight // 外层盒子可视高度
let outerScrollTop = this.$refs.scrollBox.scrollTop // 外层盒子卷去的高度
let innerScrollHeight = document.querySelector('#history-list').scrollHeight // 内层盒子全部的高度
// 当距离外层盒子底部50px的时候开始记载数据
if (((innerScrollHeight - outerScrollTop) - outerClientHeight) <= 50) {
if (this.pageFlag) {
// 每次滚动符合条件,计步器加1
this.limitWatcher++
// 每次累加10条
this.pageInfo.limit = this.limitWatcher * 10
// 关闭滚动控制开关,防止一直滚动一直累加,一直请求数据
this.pageFlag = false
this.getHistoryListData()
}
}
}
}
}
外部盒子与内部盒子代码
.history-list-box {
flex: 1;
width: 100%;
padding: 10/96rem 22/96rem .2rem 10/96rem;
box-sizing: border-box;
overflow: auto;
.history-list {
display: flex;
flex-direction: column;
align-items: center;
li {
width: 100%;
height: 108/96rem;
display: flex;
flex-direction: column;
justify-content: space-between;
.history-item {
flex: 1;
width: 100%;
padding: .2rem 0;
box-sizing: border-box;
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: -5/96rem;
.sub-flag-box {
display: flex;
flex-direction: column;
align-items: center;
width: 100/96rem;
height: 100%;
img {
width: 31/96rem;
height: 30/96rem;
margin-bottom: 11/96rem;
}
p {
font-size: 14/96rem;
color: #2E4A8F;
}
}
.sub-desc {
flex: 1;
height: 100%;
margin-left: .4rem;
display: flex;
flex-direction: column;
align-items: flex-start;
color: #ffffff;
padding: 3px 5px;
.sub-tit {
font-size: .14rem;
margin-bottom: .06rem;
color: #cccccc;
}
.sub-topic {
color: #cccccc;
font-size: .14rem;
margin-bottom: .06rem;
}
.sub-date {
color: #cccccc;
font-size: .14rem;
}
}
.sub-cancel {
opacity: 0.7;
background-image: linear-gradient(-90deg, #142A9C 0%, rgba(5,46,100,0.00) 60%);
border-radius: 3px;
}
}
.baseline {
width: 100%;
height: 2px;
background: url("../../assets/img/myReport/right-baseline.png") no-repeat center center;
background-size: 100% 100%;
}
}
}
.no-history {
width: 100%;
margin-top: .5rem;
font-size: .15rem;
}
}
/*滚动条样式*/
/*定义滚动条宽高及背景,宽高分别对应横竖滚动条的尺寸*/
.scroll-bar::-webkit-scrollbar{
width: 4px;
height: 6px;
border-radius: 10px;
background-color: transparent;
}
/*定义滚动条的轨道,内阴影及圆角*/
.scroll-bar::-webkit-scrollbar-track{
-webkit-box-shadow: inset 0 0 6px #01192B;
background-color: transparent;
border-radius: 10px;
}
/*定义滑块,内阴影及圆角*/
.scroll-bar::-webkit-scrollbar-thumb{
height: 20px;
border-radius: 10px;
-webkit-box-shadow: inset 0 0 6px #01192B;
background-color: #0672C4;
}