Vue中实现一个无限加载列表

参考 https://www.jianshu.com/p/0a3aebd63a14

 

一个需要判断的地方就是加载中再次触发滚动的时候,不要获取数据。

 

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>列表无限加载</title>
  <style>
    * {
      margin: 0;
      padding: 0;
    }
    li {
      height: 50px;
      border-bottom: 1px solid #c7c7c7;
      list-style: none;
      line-height: 50px;
      padding-left: 30px;
    }
  </style>
</head>
<body>
  <div id="unlimitedList">
    <ul>
      <li v-for="item in list">{{ item }}</li>
      <li :style="{display: loading ? 'initial' : 'none'}">Loading......</div>
    </ul>
  </div>

  <script src="https://cdn.jsdelivr.net/npm/vue@2.5.17/dist/vue.js"></script>
  <script>
    function fetch(from, size = 20) { // 模拟后台获取数据
      console.log('获取数据 传入: ', { from, size });
      let data = [];
      let total = 98;
      size = Math.min(size, total - from + 1);
      for (let i = 0; i < size; i++) {
        data.push(`列表项${from + i}`);
      }
      let ret = { data, total };
      return new Promise(function (resolve, reject) {
        setTimeout(() => {
          console.log('获取数据 返回: ', ret);
          resolve(ret);
        }, 500);
      })
    }
    new Vue({
      el: '#unlimitedList',
      data: {
        list: [],
        loading: true,    // 数据加载中
        allLoaded: false  // 数据已经全部加载
      },
      methods: {
        getData() {
          this.loading = true; // 显示加载中的标识
          fetch(this.list.length + 1).then(res => {
            this.list.splice(this.list.length, 0, ...res.data); // 将新获取到的数据连接到 this.list (vue 能检测到 splice() 函数
            this.loading = false; // 加载结束 取消加载中显示
            if (this.list.length === res.total) {
              this.allLoaded = true;
            }
          })
        },
        onScroll(e) {
          if (this.loading || this.allLoaded) return;
          let top = document.documentElement.scrollTop || document.body.scrollTop; // 滚动条在Y轴上的滚动距离
          let vh = document.compatMode == 'CSS1Compat' ? document.documentElement.clientHeight : document.body.clientHeight; // 浏览器视口的高度
          let height = Math.max(document.body.scrollHeight, document.documentElement.scrollHeight); // 文档的总高度
          if (top + vh >= height) { // 滚动到底部
            this.getData(); // 如果已经滚到底了 获取数据
          }
        }
      },
      created() {
        this.getData();
        window.addEventListener('scroll', this.onScroll);
      },
      destroyed () {
        window.removeEventListener('scroll', this.onScroll);
      }
    })
  </script>
</body>
</html>

 

posted @ 2018-10-15 19:27  我不吃饼干呀  阅读(3448)  评论(0编辑  收藏  举报