vue-infinite-scroll的使用细节介绍

邹博明
2023-12-01

scroll

适用于一个页面加载不完所有的数据,,需要分页去向后台请求数据的情景

主要的tips有以下三点

1 要监听滚轮事件,当滚轮距离底部一段距离H时,开始去请求数据

2 当在去请求数据的时候,这时就要禁止滚轮再次滚动,如果不禁止,就会出现一直会出现距离H的情况,这时候就会回到第一步骤再去重新,反复的从后台请求数据

3 定义一个滚动事件,默认为loadMore(),代表在距离为H时要触发的方法,一般内部就是请求数据的操作

以下就是选择的vue-infinite-scroll插件进行更详细的说明

安装

npm i vue-infinite-scroll -S

引用

在main.js里

import infiniteScroll from 'vue-infinite-scroll'
Vue.use(infiniteScroll)

使用

  <div class="content clearfix">
       <ul class="clearfix">
          <li class="gl-list-con" v-for="item in goodsList">
              <h3>{{item.productName}}</h3>
          </li>
       </ul> 
       <!--v-infinite-scroll-->
       <div v-infinite-scroll="loadMore" infinite-scroll-disabled="busy" infinite-scroll-distance="30">
                 .....加载中
       </div>      
  </div> 

v-infinite-scroll是放在列表的下方,,当页面进来的时候,,列表会先请求后台返回的page1的数据,然后当H为30时,触发loadMore方法,这里的busy代表是否禁用滚动事件,true代表禁用,false代表打开滚动权限。初始状态下设置为true,所以我们每次在触发loadMore方法的时候。一定要禁用滚动事件,简单的理解就是不要让屏幕再次出现有距离H的情况,然后再请求完数据的时候,,先检查一下是否还会有多余的数据,如果有的话,busy值设置为false,让屏幕再次滚动,再次触发函数,如果没有的话,就直接禁止滚动。

代码如下

  data () {
    return {
      // scroll
      busy: true, //
      },
 methods: {
    // 当属性滚动的时候  加载  滚动加载
    loadMore () {
      this.busy = true // 将无限滚动给禁用
      this.page++ // 增加页数
      this.searchSource() // 请求数据
    },
     searchSource () {
      api
        .post('/api/house/common/list', this.searchHouse)
        .then(result => {
          let listTotal = result.data.total
          if (当没有多余的数据时) {
            this.scrollDisabled = true // 将无限滚动关闭
            this.page = 0 // 页数变为0
          } else {
            this.scrollDisabled = false // 当还有多余的数据时,将无限滚动给打开 ,就是可以继续滚动去请求后台
          }
        })
        .catch(res => {
          this.$message.error('获取失败')
        })
    },

优化的地方在于,可以在loadMore的事件里加一个定时器,如果用户一直往下滑就会很快的一直去后台请求,页面就会很快的去更新,我们可以让每次触发函数的时候,间隔500毫秒,每当满足H时,500毫秒后再去请求数据,用户的体验会更好。

loadMore(){         
            this.busy=true  //将无限滚动给禁用
            setTimeout(() => {  //发送请求有时间间隔第一个滚动时间结束后才发送第二个请求
               this.page++;  //滚动之后加载第二页
              this.searchSource();
            }, 500);    

接下来的最后一关就是解决以下三种情况的页面展示问题

  • 当没有第一页数据的时候

  • 当有第一页数据的时候

    1,显示正在加载的

    2 ,显示没有更多数据

先看代码

 <el-row :gutter="20" v-show="contentShow">
          <el-col :span="8" v-for="(item, index) in houseList" :key="index">
                <div class="textCover">
                  <p><span>{{item.communityName}}</span></p>
                  <p>{{item.originLayout}}&nbsp;|&nbsp;建筑面积{{item.floorArea}}㎡</p>
                </div>
              </div>
              <div>
              </div>
          </el-col>
        </el-row>
        <el-row v-if="!contentShow">
          <p class="empty">暂时没找到相应的房源</p>
        </el-row>
        <!-- scroll -->
          <div v-show="contentShow" v-infinite-scroll="loadMore" infinite-scroll-disabled="scrollDisabled" infinite-scroll-distance="10">
            <div>
            <p v-show="infiniteMsgShow" class="tips">加载更多ing</p>
            <p v-show="!infiniteMsgShow" class="tips"> 没有更多数据</p>
            </div>
          </div>
        <!-- scroll -->

我定义了contenshow的变量,旨在确定根据返回的数据渲染页面的两种情况,在data中定义true。

 searchSource () {
      api
        .post('/api/house/common/list', this.searchHouse)
        .then(result => {
          let listTotal = result.data.total
          if (listTotal > 0) {
            this.contentShow = true
          } else {
            this.contentShow = false
          }

          this.loading = false
          this.houseList = this.houseList.concat(result.data.houses)
          let DownloadTotal =
              (this.searchHouse.page + 1) * this.searchHouse.size
          let total = result.data.total
          this.houseNum = result.data.total
          // this.searchHouse.page++; //增加页数
          if (DownloadTotal >= total) {
            this.scrollDisabled = true // 将无限滚动关闭
            this.searchHouse.page = 0 // 页数变为0
            this.infiniteMsgShow = false // 切换底部提示信息
          } else {
            this.scrollDisabled = false // 将无限滚动给打开
            this.infiniteMsgShow = true
          }
        })
        .catch(res => {
          this.$message.error('获取失败')
          this.contentShow = false
        })
    },

在请求中动态确定contenshow

  • 当有第一页内容时,scroll的dom节点也同为true,即contenshow为true

    • 定义一个infiniteMsgShow,分别渲染在没有更多数据正在加载数据这个两种情况
  • 当没有第一页数据时,显示<p class="empty">暂时没找到相应的房源</p>

    暂时就写这么多了,,发现还是有不完善的地方,后期再努力优化

 类似资料: