这里也使用了一个插件vue-infinite-scroll,滚动到底部会触发事件。
先在main.js文件里引入,
// 注册全局
import infiniteScroll from 'vue-infinite-scroll'
Vue.use(infiniteScroll)
当元素底部到达viewport底部时,将触发v-infinite-scroll值的方法(即loadMore方法)。
<div v-infinite-scroll="loadMore" infinite-scroll-disabled="busy" infinite-scroll-distance="20">
<img src="../../static/loading-spinning-bubbles.svg" v-show="loading"> //加载的图标
</div>
<div style="height:100px"></div> //这个是为了使图标清楚点显示出来
busy是指禁用与否。
然后改写前端主页,添加page(初始为1)和pageSize(每次加载几个数据)两个变量,传入后台的时候将这两个变量传上去,后台根据这两个值从数据库里取相应每页数据。
后端加
var page = req.body.page;
var pageSize = req.body.pageSize;
var skip = (page-1)*pageSize;
Article.find(param).skip(skip).limit(pageSize).sort({'_id':-1}).exec((err,doc)=>{})
常见的分页逻辑写法,跳过前size条数据,取后size条。
前端要判断是第一次取还是之后取,分为直接赋值给数组或是添加到已有数组
loadMore(){
this.busy = true;//禁用滚动方法
setTimeout(() => {
this.page++;
this.getArticles(true);
}, 500);//.5s之后向后台要数据(如果不加settimeout的话请求会成千上万,这样保证滚动一次只一个请求)
}
getArticles(flag){
this.loading = true;//显示loading图标
axios.post("/articles/articleList",{
sex:this.sex,
destination:this.destination,
goTime:this.goTime,
page:this.page,
pageSize:this.pageSize
}).then((response)=>{
let res = response.data;
this.loading = false;//隐藏loading图标
if(res.status=="0"){
if(flag){//如果不是第一次请求数据,加到数组中
this.articleList = this.articleList.concat(res.msg);
if(res.msg.length==0){//请求数据为空了
this.busy = true;//禁用滚动方法
}else{
this.busy = false;//启用滚动方法
}
}else{
this.articleList = res.msg;//如果是第一次请求数据,赋值到数组中
this.busy = false;//启用滚动方法
}
}else{ //请求出错,返回空
this.articleList=[];
this.errFlag=true;
console.log("获取服务器出现问题,请稍后重试")
}
}).then(()=>{//只显示文章前200个字符
for(var i=0;i<this.articleList.length;i++){
this.articleList[i].articleDescription = this.articleList[i].articleDescription.substr(0,200)+'……'
this.articleList[i].articleGoTime = this.articleList[i].articleGoTime.split('T')[0]
}
})
},