vue懒加载请求思路

当页面中不存在分页时,首先考虑到的就是懒加载,所以今天提供一个懒加载的思路。

首先是是么时候应该触发懒加载,以上面页面为例当页面容器中的卡片不能充满屏幕时就会触发加载出新数据,触发前提是1.已获取数据并非全部的。2.上一次请求完成了。

1.对于上面说的前提,我们设置两个变量来进行标识:

isLoading: false, // 是否处于请求状态
noMore: false,  // 是否还有为获取到的数据

2.然后就是获取数据的函数了,这里定义一个load方法来获取,并改变上一步定义的两个值。

示例:

load() {
  this.page.index += 1;
  this.isLoading = true;
  this.$axios({
    method: 'post',
    url: 'XXX',
    data: {
      "pageFilter": {
          "pageSize": this.page.size,
          "pageIndex": this.page.index,
          "sortField": "editTime",
          "sortDirection": "DESC"
      },
    }
  }).then((res) => {
    if(res.resultStatus) {
      this.isLoading = false;
      this.dataList = this.dataList.concat(res.result.content);
      this.page.total = res.totalElements;
      // 根据返回总数判断是否还存在未获取的数据
      if(res.totalElements == this.dataList.length) {
        this.noMore = true;
      }
    }
  })
}

3.当首次进入页面/切换筛选条件等情况时,除了要调用load方法,还需进行事件绑定, 而符合条件的就是scroll于resize了(滚动与放大缩小)。

getList() {
  this.dataList = [];
  this.isLoading = false;
  this.noMore = false;
  window.addEventListener('scroll', this.setListener, true);
  window.addEventListener('resize', this.setListener, true);
  this.load();

},
setListener() {
  let scrollDiv = document.querySelector('.scrollDiv');
  let innerDiv = document.querySelector('.innerDiv');
    // 重点,判断当前视角是否触及页面底部,20是误差值
    if(scrollDiv.scrollTop + scrollDiv.clientHeight > innerDiv.clientHeight - 20) {
      this.load();
    }
},

4.最后,再load中添加--无未获取数据与正在请求中这两种特殊情况下的约束,防止重复请求:

// load中添加
if(this.isLoading || this.noMore) {
  if(this.noMore) {
    window.removeEventListener('scroll', this.setListener, true);
    window.removeEventListener('resize', this.setListener, true);
  }
  return false;
}

总体参考代码:

<!DOCTYPE html>
<html>

<head>
  <meta charset="UTF-8">
  <!-- import CSS -->
  <link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
</head>
<style scoped>
  #app {
    height: 80vh;
  }
  .scrollDiv {
    overflow-y: scroll;
    height: 100%;
  }
  .innerDiv {
    padding: 20px;
    position: relative;
  }
  .divBox {
    width: 350px;
    height: 200px;
    display: inline-block;
    border: 1px solid rebeccapurple;
    margin: 10px;
    vertical-align: top;
  }
</style>

<div id="app">
  <div class="scrollDiv">
    <div class="innerDiv">
      <div v-for="item, index in dataList" class="divBox">
        {{item.projectName}}
      </div>
    </div>
  </div>
</div>

<script>
  new Vue({
    el: '#app',
    created() {
      this.getList();
    },
    data: function () {
      return {
        dataList: [],
        isLoading: false, // 是否处于请求状态
        noMore: false,  // 是否还有为获取到的数据
        page: {
          size: 5,
          index: 0,
          total: 0
        }
      }
    },
    methods: {
      getList() {
        this.dataList = [];
        this.isLoading = false;
        this.noMore = false;
        window.addEventListener('scroll', this.setListener, true);
        window.addEventListener('resize', this.setListener, true);
        this.load();

      },
      setListener() {
        let scrollDiv = document.querySelector('.scrollDiv');
        let innerDiv = document.querySelector('.innerDiv');
          console.log(scrollDiv.scrollTop + scrollDiv.clientHeight > innerDiv.clientHeight - 20)
          if(scrollDiv.scrollTop + scrollDiv.clientHeight > innerDiv.clientHeight - 20) {
            this.load();
          }
      },
      load() {
        if(this.isLoading || this.noMore) {
          if(this.noMore) {
            window.removeEventListener('scroll', this.setListener, true);
            window.removeEventListener('resize', this.setListener, true);
          }
          return false;
        }
        this.page.index += 1;
        this.isLoading = true;
        this.$axios({
          method: 'post',
          url: 'XXX',
          data: {
            "pageFilter": {
                "pageSize": this.page.size,
                "pageIndex": this.page.index,
                "sortField": "editTime",
                "sortDirection": "DESC"
            },
          }
        }).then((res) => {
          if(res.resultStatus) {
            this.isLoading = false;
            this.dataList = this.dataList.concat(res.result.content);
            this.page.total = res.totalElements;
            // 根据返回总数判断是否还存在未获取的数据
            if(res.totalElements == this.dataList.length) {
              this.noMore = true;
            }
          }
        })
      }
    }
  })
</script>

</html>

ps: 当首页请求的数据不足以填满整个屏幕的时候,可以在load中的数据请求回调中补充调用一次setListener方法,进而自动触发。

}).then((res) => {
  if(res.resultStatus) {
    this.isLoading = false;
    this.dataList = this.dataList.concat(res.result.content);
    this.page.total = res.totalElements;
    if(res.totalElements == this.dataList.length) {
      this.noMore = true;
    };
    // 补充
    this.setListener();
  }
})

好的,以上就是全部内容了,欢迎大家前来讨论,希望本文会对您有所帮助~ ^_^

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值