效果如下
CV大法
<template>
<h1>横向无限滚动</h1>
<div id="app" class="scroll-container" @scroll="handleScroll">
<div v-for="(item, index) in items" :key="index" class="item">
{{ item }}
</div>
<div v-if="isLoading" class="loader">加载中...</div>
</div>
</template>
<script setup lang="ts">
import { ref, reactive, Ref, onMounted } from 'vue'
const items: any = ref([]) // 存储项目数组
const isLoading = ref(false) // 是否正在加载数据
const page = ref(1) // 当前页数
// 假设这是从服务器获取数据的函数
const fetchData = async (pageNum: any) => {
// 这里需要你的数据获取逻辑
// 例如:await api.getData(pageNum);
// 这里我们只是模拟一些数据
const newData = Array.from({ length: 10 }, (_, index) => `项目 ${pageNum * 10 + index + 1}`)
return newData
}
// 处理滚动事件
const handleScroll = (event: any) => {
const container = event.target
const { scrollLeft, scrollWidth, clientWidth } = container
// 接近滚动容器右边界时加载新数据
if (scrollWidth - scrollLeft - clientWidth <= 100) {
if (!isLoading.value) {
isLoading.value = true
fetchData(page.value).then((newItems: any) => {
// 更新数据
items.value = items.value.concat(newItems)
// 更新页数
page.value += 1
// 加载完毕
isLoading.value = false
})
}
}
}
// 组件挂载后初始化
onMounted(() => {
// 初始加载数据
fetchData(1).then(initialItems => {
items.value = initialItems
})
})
</script>
<style lang="less" scoped>
.scroll-container {
display: flex;
overflow-x: auto;
white-space: nowrap;
}
.item {
flex: 0 0 auto;
width: 200px; /* 假设每个项目宽度为200px */
height: 100px;
margin-right: 10px; /* 如果有间距 */
/* 其他样式 */
}
.loader {
width: 100px;
height: 100px;
/* 加载样式 */
}
.scroll-container::-webkit-scrollbar {
display: none; /* 在浏览器中隐藏滚动条 */
}
</style>