最近想写个网站需要滚动加载的功能,用了element的infinite-scroll感觉局限太大,干脆自己写一个,功能如下
image
原理
vue实现滚动到底部加载数据的原理是监听页面滚动,当页面滚动到底部的时候,前端从后端获取分好页的数据加入到datas[]数组中,进行渲染,就实现了滚动加载的功能
先了解几个关键词:
(1)滚动条到顶部的位置:scrollTop
(2)当前窗口内容可视区:windowHeight
(3)滚动条内容的总高度:scrollHeight
触发监听滚动条的函数是:
window.onscroll = ()=>{...}
判断到底部的等式: scrollTop+windowHeight=scrollHeight;
实现
我用的是vue脚手架搭的项目,都写在App.vue文件里,代码如下
App.vue文件
{ {data}}
export default {
name: 'app',
data() {
return {
datas:[],
testdatas:['1','2','3','4','5'], //初始加载测试数据
count:5, //默认加载数量
isAchiveBottom: false //滚动条是否到底部标志
}
},
created() {
//使用window.onscroll = function(){}this指向出现问题
//故应该使用箭头函数,因为箭头函数无this,会从上一级找,故会找到vue实例的this
window.onscroll = () => {
//变量scrollTop是滚动条滚动时,距离顶部的距离
var scrollTop =
document.documentElement.scrollTop || document.body.scrollTop;
//变量windowHeight是可视区的高度
var windowHeight =
document.documentElement.clientHeight || document.body.clientHeight;
//变量scrollHeight是滚动条的总高度
var scrollHeight =
document.documentElement.scrollHeight || document.body.scrollHeight;
//滚动条到底部的条件(距底部20px时触发加载)
if (
scrollTop + windowHeight >= scrollHeight - 20 &&
!this.isAchiveBottom &&
!this.noMore
) {
// console.log(
// "距顶部" +
// scrollTop +
// "可视区高度" +
// windowHeight +
// "滚动条总高度" +
// scrollHeight
// );
this.isAchiveBottom = true;
//延时触发数据加载
setTimeout(() => {
//后端需要进行分页,然后前端从后端拿来实现滚动加载
//这里利用数组push来模拟从后端拿到的数据
this.datas.push("test");
this.isAchiveBottom = false;
}, 500);
}
};
},
beforeMount() {
// 在页面挂载前就发起请求
this.getInitial();
},
methods: {
getInitial(){
for (var i = 0; i < this.count; i++) {
this.datas.push(this.testdatas[i]);
}
}
},
}
#app {
font-family: 'Avenir', Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
.list{
background-color: #d2d2d2;
border-radius: 3px;
width: 50%;
height: 150px;
line-height: 150px;
margin: 0 auto 20px auto;
}
github项目地址