<template>
<scroll-view
scroll-y
:style="scrollStyle"
@scrolltolower="handleScrollToLower"
lower-threshold="50"
:scroll-with-animation="true"
>
<view class="content-box">
<!-- 列表渲染 -->
<view v-for="item in list" :key="item.id">{{ item.title }}</view>
<!-- 加载状态组件 -->
<uni-load-more :status="loadStatus" :icon-size="16"/>
</view>
</scroll-view>
</template>
<script setup>
import { ref, reactive, onMounted } from 'vue'
import { onReachBottom } from '@dcloudio/uni-app'
// 响应式数据
const list = ref([]) // 数据列表
const page = ref(1) // 当前页码
const per_page = ref(10)
const total = ref(0) // 总数据量
const loadStatus = ref('more') // 加载状态(more/loading/noMore)
const scrollStyle = reactive({ // 滚动容器样式
height: '0px'
})
// 生命周期
onMounted(() => {
calcScrollHeight()
loadData()
})
// 计算滚动容器高度
const calcScrollHeight = () => {
const { windowHeight } = uni.getSystemInfoSync()
scrollStyle.height = `${windowHeight - 50}px` // 减去顶部导航栏高度
}
// 加载数据方法
const loadData = async () => {
try {
loadStatus.value = 'loading'
const res = await uni.request({
url: '/api/list',
method: 'GET',
data: { page: page.value,per_page: per_page.value, }
})
// 更新数据
list.value = page.value === 1
? res.data.rows
: [...list.value, ...res.data.rows]
total.value = res.data.total
updateLoadStatus()
} catch (error) {
console.error('数据加载失败:', error)
page.value = Math.max(1, page.value - 1) // 失败时回退页码
} finally {
loadStatus.value = 'more'
}
}
// 更新加载状态
const updateLoadStatus = () => {
loadStatus.value = list.value.length >= total.value
? 'noMore'
: 'more'
}
// 滚动触底事件处理(带防抖)
let isLoading = false
const handleScrollToLower = () => {
if (isLoading || loadStatus.value === 'noMore') return
isLoading = true
page.value += 1
loadData().finally(() => {
isLoading = false
})
}
</script>
<style scoped>
/* 保持原有样式不变 */
.content-box {
padding: 20rpx;
}
</style>
uniapp上滑加载
于 2025-03-22 18:24:20 首次发布