手机端上拉加载页面,在vue.js框架里面实现,因为用其他包的话,其实用不到那么多功能,都不好意思用包-_- ---所有的代码都有注释说明
data
data () {
// 因为这里的有三个tab,所以先定义一个循环,主要是在切换的时候改变文字以及传参,
// 如果你只有一个列表,可以忽略
const tabList = [
{
text: '本月收入',
img: 'monthIncome',
rankType: 1,
dateType: 1,
},
{
text: '总收入',
img: 'totalIncome',
rankType: 2,
dateType: 2,
},
{
text: '最高速度',
img: 'highSpeed',
rankType: 3,
dateType: 3,
},
]
// size是固定的,为了做到修改一次size,就能改变所有地方的size,所以抽出来定义
const size = 2
return {
tabList,
currentIndex: 0,
rankList: [], // 数据列表
size,
rankParams: {
rankType: 1,
dateType: 1,
page: 1,
size,
},
more: true, // 是否还有分页的数据
total: 0, // 数据总条数
triggerDistance: 10, // 滚动加载阈值
isLastData: false, // 是不是最后一页
}
},
template
tab的代码 (有删减,只留基本解构,保留@click="changeRankType(item,index))
<div v-for="(item,index) in tabList" :key="index" @click="changeRankType(item,index)">
<img
class="month-income"
:src="require(`@/assets/image/starMine/${item.img}.png`)"
>
</div>
列表的代码
<div class="ranking-list-bg">
<div class="ranking-list" ref="rankingRef" @touchend="touchEnd">
<div class="ranking-list-info" v-for="(item,index) in rankList" :key="index">
<commonItem
:currentIndex="currentIndex"
:index="index"
:is-mine="false"
:user-info="item.user"
:user-value="item.value"
/>
</div>
<!--最后一条-->
<div v-show="this.rankParams.page !== 1 && isLastData" class="rank-last-data">
<div class="rank-last-data-line"></div>
<div class="rank-last-data-text">到底啦~</div>
</div>
</div>
</div>
这里最重要的就是ref="rankingRef" @touchend="touchEnd",后续会用到
methods && mounted
async mounted () {
this.getRankingList()
},
methods: {
async getRankingList () {
const { ranks, total } = await getMineRankApi(this.token, this.rankParams)
// 每一次下拉都要把数据push进去
this.rankList.push(...ranks)
// 拿到总条数
this.total = total
// 如果目前的页数小于或者等于(总页数/美页条数),表示还可以加载,反之,不能
this.more = this.rankParams.page <= (this.total / this.rankParams.size)
// 当页数大于或者等于(总页数/美页条数), 可以显示已经到底了
if (this.rankParams.page >= +(this.total / this.rankParams.size)) {
this.isLastData = true
}
},
// 切换tab
changeRankType ({ rankType, dateType }, index) {
// 因为三个tab实际上用的是同一个接口,在切换时,必须将page,size重置,将其他参数动态写入
// 必须将是否到底进行重置为false
// 必须将列表进行重置为空数组
this.currentIndex = index
this.isLastData = false
this.rankParams = {
rankType,
dateType,
page: 1,
size: this.size,
}
this.rankList = []
this.getRankingList()
},
touchEnd () {
// 如果不能下拉页数超过总页数,return
if (!this.more) {
return
}
// 元素的内容垂直滚动的高度 + 元素可视高度 + 阈值 > 元素的的所有的高度(卷起来+ 可视)
if (this.$refs.rankingRef.scrollTop
+this.$refs.rankingRef.offsetHeight
+ this.triggerDistance > this.$refs.rankingRef.scrollHeight) {
this.rankParams.page += 1
this.getRankingList()
}
},
},
参考scrollTop offsetHeight scrollHeight
这里我觉得最重要的就是什么时候进行滑动? scrollTop表示的是元素滚动的高度,offsetHeight表示元素的高度,scrollHeight表示的是总高度(包含卷起),那么如果scrollTop + offsetHeight = scrollHeight,表示我手已经滑倒最底部了,但是不可能只有在最底部才能滑动,所以要加上一个阈值,给他一个滑动的区间.
当我没有滚动时,scrollTop = 0, 没有分页但是元素超出一屏幕的时候,scrollTop + offsetHeight < scrollHeight
阈值越大,表示在越上面就能加载到下一页
css
.ranking-list {
height: 900px; // 这里最好给一个高度
overflow: scroll;
}