先看下效果:
代码:
<template>
<div>
<div style="text-align: center">
<button @click="scrollTop">滚动到顶部</button>
<button @click="scrollBottom">滚动到底部</button>
</div>
<div class="scroll_wrap" ref="scrollWrap">
<div v-for="(s, i) in list" :key="i" class="item">{{ s }}</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
list: [],
noMore: false, //暂无更多数据
};
},
mounted() {
this.initData();
this.scrollBottom();
this.$refs.scrollWrap.addEventListener("scroll", this.onScrollListener);
},
methods: {
//滚动监听
onScrollListener() {
if (this.$refs.scrollWrap.scrollTop == 0) {
console.log("滚动到顶部了");
if (this.noMore) {
this.$baseUI.showToast("暂无更多数据");
return;
}
this.$baseUI.showLoading();
//模拟耗时任务从接口获取数据
setTimeout(() => {
const scrollWrap = this.$refs.scrollWrap;
let h1 = scrollWrap.scrollHeight;
console.log("h1======" + h1);
this.loadMoreData();
this.$baseUI.hideLoading();
//list更新后,等待页面渲染完毕再去拿scrollHeight,否则拿到的是之前的
this.$nextTick(() => {
let h2 = scrollWrap.scrollHeight;
console.log("h======" + h2);
//顶部在原先基础上往下滚动50px,露出新加载数据的一点
scrollWrap.scrollTo({
top: h2 - h1 - 50,
behavior: "instant", //auto-自动滚动 instant-瞬间滚动 smooth-平滑滚动
});
});
}, 1000);
}
},
//滚动到顶部
scrollTop() {
this.$nextTick(() => {
const scrollWrap = this.$refs.scrollWrap;
scrollWrap.scrollTo({
top: 0,
behavior: "smooth", //auto-自动滚动 instant-瞬间滚动 smooth-平滑滚动
});
});
},
//滚动到底部
scrollBottom() {
this.$nextTick(() => {
let scrollWrap = this.$refs.scrollWrap;
scrollWrap.scrollTo({
top: scrollWrap.scrollHeight,
behavior: "smooth", //auto-自动滚动 instant-瞬间滚动 smooth-平滑滚动
});
});
},
//加载更多数据
loadMoreData() {
let arr = [];
for (let i = this.list.length; i < 10 + this.list.length; i++) {
arr.unshift("data --- " + i);
}
this.list = [...arr, ...this.list];
if (this.list.length == 40) {
this.noMore = true; //数据全部加载完毕
}
},
//初始化数据
initData() {
for (let i = 0; i < 20; i++) {
this.list.unshift("data --- " + i);
}
},
},
beforeDestroy() {
this.$refs.scrollWrap.removeEventListener("scroll", this.onScrollListener);
},
};
</script>
<style lang="less" scoped>
.scroll_wrap {
width: 300px;
height: 500px;
position: absolute;
top: 30px;
left: 50%;
transform: translateX(-50%);
border: 1px solid #333;
overflow: auto;
.item {
height: 50px;
line-height: 50px;
padding-left: 15px;
border-bottom: 1px solid #e4e4e4;
}
}
</style>