vue触底加载更多数据简易版本
<template>
<div>
<div class="container" style="overflow-x: auto">
<div class="scroll-container" ref="scrollContainers">
<ul class="uls">
<li
class="lis"
:class="active === index ? 'isActive' : ''"
v-for="(item, index) in list"
:key="index"
@click="activeList(index)"
>
{{ item }}
</li>
</ul>
</div>
</div>
<ul
class="ul"
style="height: 200px; overflow-y: scroll"
ref="scrollContainer"
>
<li class="li" v-for="(item, index) in diffExpect.data" :key="index">
{{ item }}
</li>
</ul>
</div>
</template>
<script setup>
import { ref, onMounted, reactive } from "vue";
const list = ref([
"热点",
"新闻",
"神话",
"小说",
"杂志",
"怪志奇谈",
"武侠传记",
]);
const active = ref(0);
const dataArray = new Array(1000).fill({
date: "2016-05-03",
name: "Tom",
address: "No. 189, Grove St, Los Angeles",
age: 23,
});
// 监听滚动事件
onMounted(() => {
scrollContainer.value.addEventListener("scroll", handleScroll);
});
// 滚动容器的引用
const scrollContainer = ref(null);
const diffExpect = reactive({ data: dataArray.slice(0, 8) });
const copyTabData = reactive({ data: dataArray }); // 拷贝一份 tableData 的值
const pageNo = ref(1);
const pageSize = ref(8);
const total = ref(1000); // 这里需要获取总数据的条数
const isHasNextPage = () => {
return pageNo.value < Math.ceil(total.value / pageSize.value);
};
var throttle = function (func, delay) {
var prev = Date.now();
return function () {
var context = this;
var args = arguments;
var now = Date.now();
if (now - prev >= delay) {
func.apply(context, args);
prev = Date.now();
}
};
};
let timer = null;
const handleScroll = throttle((event) => {
const scrollContainer = event.target;
const scrollHeight = scrollContainer.scrollHeight;
const scrollTop = scrollContainer.scrollTop;
const clientHeight = scrollContainer.clientHeight;
if (
// 30 li的 margin-bottom: 30px;
scrollTop + clientHeight + 30 >= scrollHeight &&
isHasNextPage &&
!timer
) {
console.log("触底加载");
pageNo.value += 1;
timer = setTimeout(() => {
const concatList = copyTabData.data.slice(
pageNo.value * pageSize.value,
pageNo.value * pageSize.value + 8
);
diffExpect.data = diffExpect.data.concat(concatList);
timer = null;
}, 80);
}
}, 90);
const reset = () => {
diffExpect.data = copyTabData.data.slice(0, 8);
pageNo.value = 0;
};
const scrollContainers = ref(null);
const scrollItemIntoView = (index) => {
const listItem = scrollContainers.value.getElementsByClassName("lis")[index];
listItem.scrollIntoView({ behavior: "smooth", inline: "center" });
};
const activeList = (index) => {
active.value = index;
scrollItemIntoView(index);
// 使用参数进行下一步的接口联调
reset();
setTimeout(() => {
scrollContainer.value.addEventListener("scroll", handleScroll);
}, 500);
};
</script>
<style scoped>
li {
list-style: none;
}
.container {
width: 400px;
white-space: nowrap;
}
/* 自定义滚动条的样式 */
.container::-webkit-scrollbar {
width: 3px;
}
.scroll-container {
scroll-behavior: smooth;
}
.uls {
display: inline-flex;
padding: 10px;
}
.lis {
flex: 0 0 auto;
padding: 8px;
background-color: #ccc;
margin-right: 10px;
}
.isActive {
background: skyblue;
color: #fff;
cursor: pointer;
}
.li {
list-style: none;
margin-bottom: 30px;
color: #e4e4e4;
}
.ul {
background: skyblue;
}
/* 自定义滚动条的样式 */
.ul::-webkit-scrollbar {
width: 8px;
background: rgba(238, 238, 238, 0.2);
}
::-webkit-scrollbar-thumb {
background-color: dimgrey;
border-radius: 5px;
opacity: 0.7;
}
::-webkit-scrollbar-track {
background-color: #e4e4e4;
border-radius: 2px;
}
</style>