分页功能的一种形式

vue-infinite-loading

经常用的 Vue 滚动加载组件
他最大的好处是 “使用起来不在乎滚动条是谁的”,用用就知道了,很方便
可以理解为,只要显示出该组件,就会触发一次滚动加载

2022.06.28
刚完成了一个向上的滚动加载需求,怀着感谢的心情特来标注以下:
做向上的滚动加载,不需要自己处理滚动条的位置,组件内部给实现了。
自己只需要拼数据就可以了,但是要注意,像图片这种,需要用预加载的方式,消除影响再 loaded。

各种链接整理

使用心得以及常用代码记录

  1. 首屏加载也统一使用滚动加载逻辑

因为如果不走滚动加载逻辑的话,请求有延迟
组件由于没有内容支撑父元素高度,会直接触发滚动加载,会按照没有任何数据的情况下,跑一遍逻辑
而这一遍的结果通常是错误的,比如说 “无数据” 等,代码结构还比较乱

实用代码在下面,为了防止各种情况请求触发两次的情况
所以在请求前和请求后都判断下是否可以执行滚动加载
注意:下面的代码依赖 total 判断,所以不要初始把 total 设置为 0,默认为 null 即可

PS:主要的代码是 infiniteHandler 函数,以及 identifier 的处理

  <!-- 滚动加载 -->
  <infinite-loading
    ref="infinite"
    :identifier="infiniteId"
    @infinite="infiniteHandler">
    <template slot="no-more">没有更多了</template>
    <template slot="no-results">没有查到数据</template>
  </infinite-loading>
data: function () {
  return {
    // 数据和分页字段
    dataList: [],
    page: 1,
    pageSize: 10,
    total: 0,
    
    // 该属性只为了重置组件,比如说列表筛选项切换后
    // 重置之前的已完成状态,只需要改变该值即可
    infiniteId: 0
  }
}
methods: {
  // 滚动加载
  infiniteHandler: function ($state) {
    var _this = this
    
    // 若数据集不存在或者数量为 0,那么逻辑肯定是请求第一页
    // 如果数据集已经有值了,那么该逻辑是请求下一页
    var page = this.page = (!this.dataList || this.dataList.length === 0) ?
      1 :
      this.page + 1
    
    this.$http
      .post('xxxxx', {
        page: this.page,
        pageSize: this.pageSize
      })
      .then(function (res) {
        _this.total = res.body.total
        _this.dataList = (_this.dataList || []).concat(res.body.list || [])
        
        // 标识 "已完成了当次加载"
        $state.loaded()
        
        // 判断是否有下一页,若无,则标识 "已无更多了"
        if (_this.page >= Math.ceil(_this.total / _this.pageSize)) {
          $state.complete()
        }
      })
  },
  // 修改了筛选条件
  changeFilter: function () {
    this.dataList = []
    this.infiniteId += 1
  },
}