美文网首页
vue无限加载

vue无限加载

作者: 一名有马甲线的程序媛 | 来源:发表于2018-03-23 18:02 被阅读49次

vue无限加载

template:

<template>
 <div v-scroll="loadMore">
  <ul class="news">
   <li class="news__item" v-for="(news, index) in newslist">
    {{index}}-{{news.title}}
   </li>
  </ul>
 </div>
</template>

js:

<script>
 export default{
  data(){
   return{
    newslist: [
     {title: 'hello world'},
     {title: 'hello world'},
     {title: 'hello world'},
     {title: 'hello world'},
     {title: 'hello world'},
     {title: 'hello world'},
     {title: 'hello world'},
     {title: 'hello world'},
     {title: 'hello world'},
     {title: 'hello world'}
    ]
   }
  },
  methods: {
   loadMore() {
    let newAry = [];
    for(let i = 0; i < 10; i++) {
     newAry.push({title: 'hello world'})
    }
    this.newslist=this.newslist.concat(newAry);
   }
  },
  directives: {
   scroll: {
    bind: function (el, binding){
     window.addEventListener('scroll', ()=> {
      if(document.documentElement.scrollTop + window.innerHeight >= el.clientHeight) {
        console.log('scrollTop:'+document.documentElement.scrollTop+',innerHeight'+window.innerHeight+',clientHeight'+el.clientHeight);
        let fnc = binding.value;  
        fnc(); 
      }
     })
    }
   }
  }
 }
</script>

css:

<style>
 .news__item {
  height: 80px;
  border: 1px solid #ccc;
  margin-bottom: 20px;
 }
</style>

js无限加载

先了解三个变量:

  • document.documentElement.scrollTop 滚动条滚动的距离
  • window.innerHeight 浏览器窗口高度
  • document.body.clientHeight 内容高度

html:

<body>
    <div class="container">
     <ul class="news" id="news">
      <li class="news__item">1、hello world</li>
      <li class="news__item">2、hello world</li>
      <li class="news__item">3、hello world</li>
      <li class="news__item">4、hello world</li>
      <li class="news__item">5、hello world</li>
      <li class="news__item">6、hello world</li>
      <li class="news__item">7、hello world</li>
      <li class="news__item">8、hello world</li>
      <li class="news__item">9、hello world</li>
      <li class="news__item">10、hello world</li>
     </ul>
    </div>
</body>

js:

<script>
    var scrollDisable = false;
    window.addEventListener('scroll', function() {
     var scrollTop = document.documentElement.scrollTop;
     if(scrollTop + window.innerHeight >= document.body.clientHeight) {
        // if(!scrollDisable){
            // 触发加载数据    
            loadMore();
            console.log('scrollTop:'+scrollTop+',innerHeight:'+window.innerHeight+',clientHeight:'+document.body.clientHeight);

        // }
     }
    });

    // 表示列表的序号
    var index = 10;
    function loadMore() {
     // 开始加载数据,就不能再次触发这个函数了
     scrollDisable = true;
     var content = '';
     for(var i=0; i< 10; i++) {
      content += '<li class="news__item">'+(++index)+'、hello world</li>' 
     }
     var node = document.getElementById('news');
     // 向节点内插入新生成的数据  
     var oldContent =   node.innerHTML;
     node.innerHTML = oldContent+content;
    }
</script>

优化:
上面的例子并没有真正从接口获取数据,所以存在一个隐藏的 bug:当接口响应很慢的情况,滚动到底部正在加载数据时,稍微滚动一下仍会触发获取数据函数,这会造成同时请求多次接口,一次性返回大量数据。
解决办法是添加一个全局变量 scrollDisable,当第一次触发加载数据函数时,将该值设置为 true,根据该值判断是否要执行加载函数。

css:

<style>
 * {
  -webkit-box-sizing: border-box;
  -moz-box-sizing: border-box;
  box-sizing: border-box;
  }
 li, ul {
  list-style: none;
 }
 .container {
  width: 980px;
  margin: 0 auto;
 }
 .news__item {
  height: 80px;
  margin-bottom: 20px;
  border: 1px solid #eee;
 }
 </style>

点击查看原文

相关文章