先看下效果:
代码:
<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>