Vue如何优雅地实现下拉到底部自动加载(无限滚动)

晴和君 · 2019年12月30日 · 24次阅读 · 预计需要4分钟

今天在制作闲言碎语页面时,想要一个无限滚动的功能。本来想用 Element UI 自带的无限滚动,但是发现这个貌似需要有一个定高的容器,那就很不适合我了。我想要的是整个页面的无限滚动,而不是容器内的无限滚动。所以在网上找到了一篇很不错的文章,来分享一下,根据自己需求修改就好。

首先在目录下新建一个utils文件夹,在该文件夹下新建一个screen.js,将公用方法写入,你也可以考虑其他的封装方式。

//滚动条在 Y 轴上的滚动距离
export function getScrollTop(){
  var scrollTop = 0, bodyScrollTop = 0, documentScrollTop = 0;
  if(document.body){
    bodyScrollTop = document.body.scrollTop;
  }
  if(document.documentElement){
    documentScrollTop = document.documentElement.scrollTop;
  }
  scrollTop = (bodyScrollTop - documentScrollTop > 0) ? bodyScrollTop : documentScrollTop;
  return scrollTop;
}



//文档的总高度
export function getScrollHeight(){
  var scrollHeight = 0, bodyScrollHeight = 0, documentScrollHeight = 0;
  if(document.body){
    bodyScrollHeight = document.body.scrollHeight;
  }
  if(document.documentElement){
    documentScrollHeight = document.documentElement.scrollHeight;
  }
  scrollHeight = (bodyScrollHeight - documentScrollHeight > 0) ? bodyScrollHeight : documentScrollHeight;
  return scrollHeight;
}



//浏览器视口的高度
export function getWindowHeight(){
  var windowHeight = 0;
  if(document.compatMode == "CSS1Compat"){
    windowHeight = document.documentElement.clientHeight;
  }else{
    windowHeight = document.body.clientHeight;
  }
  return windowHeight;
}

在要使用的页面中进行引入

import {getScrollHeight,getScrollTop,getWindowHeight} from "../../utils/screen";

将窗口的滚动进行监听,划到底部的时候就进行加载,但是页面关闭的同时,记得将这个监听器关闭,节省性能

mounted(){
    window.addEventListener('scroll', this.load);
},
destroyed(){
    window.removeEventListener('scroll', this.load, false);
},

this.load()就是写的加载数据的方法,到底部的时候先判断下一页是否还有数据,pages 就是我从后台拿到的总页数,和当前页进行对比,只有下一页还有数据的时候,我才会拉取后台的接口。

//无限滚动加载
load(){
    let vm=this;
    if(getScrollTop() + getWindowHeight() >= getScrollHeight()){
        if(vm.queryList.pageNum < vm.pages){      //先判断下一页是否有数据  
            vm.queryList.pageNum+=1;         //查询条件的页码+1
            vm.getList();              //拉取接口数据
        }else{
            //到底了
        }
    }
},
5分