项目背景:
项目使用 uniapp(vue) 开发;
由于是内嵌组件
display: block; height: 100%; width: 100%; overflow-y: scroll; overflow-x: hidden;
无法使用 onReachBottom 来完成是否到达底部;
所以思路了就是:
通过 scroll滚动时候 判断 列表最后一个元素 距离容器顶部的距离;来判断是否到达底部!
给列表最后一个元素添加 标记 :'item-last'
<dispatch-item class="item" :tabKey='tabKey' :datum='item' v-for="(item,subIndex) in itemArray" :key="subIndex"
@click.native="onDetail(item)" :class="[subIndex===itemArray.length-1?'item-last':'']">
然后在 onScroll 中进行监听:
onScroll(e) {
if (this.isLoading && this.itemArray.length >= this.total) {
return
}
this.query.select('.item-last').boundingClientRect(data => {
//console.log('----->item-last:', data)
if (data && data.bottom <= this.tabbarData.bottom) {
console.log("到底了")
if (this.isLoading) {
this.isLoading = false
this.page += 1
this.onRefrsh()
}
}
}).exec();
}
完整代码:
<template>
<view class="task-pispatched-tabbar" @scroll="onScroll">
<fruit-page v-if="isLoading && itemArray.length === 0"></fruit-page>
<view v-else style="display: block;">
<dispatch-item class="item" :tabKey='tabKey' :datum='item' v-for="(item,subIndex) in itemArray" :key="subIndex"
@click.native="onDetail(item)" :class="[subIndex===itemArray.length-1?'item-last':'']">
<template slot="itemBottom">
<view class="task-item-await" v-if="tabKey === 0">
<image src="/static/task/[email protected]" mode=""></image>
<view class="task-await-title">
派发{
{item.userNoticeSum}}人,{
{item.userAcceptSum}}人接受
</view>
<view class="task-await-button">
增加派发
</view>
</view>
<view class="task-item-await" v-else-if="tabKey === 1">
<image src="/static/task/[email protected]" mode=""></image>
<view class="task-await-title">
接受{
{item.userAcceptSum}}人,{
{item.userRunSum}}人出发
</view>
</view>
<!-- <view class="task-item-await" v-else-if="tabKey === 2">
<image src="/static/task/[email protected]" mode=""></image>
<view class="task-await-title">
派发{
{item.userNoticeSum}}人,{
{item.userAcceptSum}}人接受
</view>
</view> -->
</template>
</dispatch-item>
</view>
</view>
</template>
<script>
import dispatchItem from './taskDispatchedItem.vue'
import fruitPage from '@/components/uni-z-fruit-page/fruit-page.vue'
export default {
data() {
return {
itemArray: [],
page: 1,
pageSize: 15,
total: 0,
isLoading: false,
query: null,
tabbarData: null
}
},
props: {
tabKey: {
type: Number,
default: 1
}
},
components: {
dispatchItem,
fruitPage
},
mounted() {
this.query = uni.createSelectorQuery().in(this)
uni.createSelectorQuery().in(this).select('.task-pispatched-tabbar').boundingClientRect(data => {
//console.log("-->tabbar:", data)
this.tabbarData = data
//console.log("-->tabbarData:", this.tabbarData)
}).exec();
this.onRefrsh()
},
methods: {
async onRefrsh() {
const data = {
buildType: 2,
page: this.page,
limit: this.pageSize,
state: this.tabKey + 2
}
if (this.tabKey === 0) {
data.state = 5
} else {
data.state = this.tabKey + 2
}
const res = await this.$http.tasks(data)
if (res) {
this.itemArray = this.itemArray.concat(res.rows)
this.total = res.total
}
//console.log('----:', res)
this.isLoading = true
},
onDetail(item) {
console.log('item:', item)
uni.navigateTo({
url: `/main/pages/task/taskDispatchDetail?id=${item.id}&type=${this.tabKey}`
})
},
onScroll(e) {
if (this.isLoading && this.itemArray.length >= this.total) {
return
}
this.query.select('.item-last').boundingClientRect(data => {
//console.log('----->item-last:', data)
if (data && data.bottom <= this.tabbarData.bottom) {
console.log("到底了")
if (this.isLoading) {
this.isLoading = false
this.page += 1
this.onRefrsh()
}
}
}).exec();
}
}
}
</script>
<style lang="scss" scoped>
.task-pispatched-tabbar {
display: block;
height: 100%;
width: 100%;
overflow-y: scroll;
overflow-x: hidden;
.item {
.task-item-await {
width: 100%;
height: 120rpx;
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
image {
margin-left: 24rpx;
width: 30rpx;
height: 30rpx;
}
.task-await-title {
margin-left: 6rpx;
margin-right: auto;
color: #3a81fc;
font-size: 28rpx;
}
.task-await-button {
display: block;
margin-right: 24rpx;
color: #FFFFFF;
width: 144rpx;
height: 64rpx;
line-height: 64rpx;
text-align: center;
background: #3a81fc;
border-radius: 18rpx;
}
}
.item:last-child {
padding-bottom: 40rpx;
}
}
}
</style>