美文网首页
滚动加载的列表

滚动加载的列表

作者: Geeker工作坊 | 来源:发表于2020-03-06 00:50 被阅读0次

开始之前

今儿的项目又遇见一个不按套路出牌的设计:一个列表页,设计图上是不分页查询,后台给的接口是分页查询。跟产品说加个分页,产品说用户就不想要分页(任性呀!)。可这么多数据一次性返回肯定是不行的,接口响应时间太长了。现在的爸爸们真的越来越有(难)品(伺)味(候)了。为了解决这个问题,决定把移动端常见的滚动加载放进来。

代码开撸

关于滚动加载的原理简单来讲就是我们设置一个高度固定的列表,当数据超过列表的高度,我们将产生出的滚动条拖拉到底部,到底部的时刻我们触发一次数据请求,把请求的数据添加数据列表中,触发页面重渲染就可以完成。没有想象中那么复杂。项目是基于Vue 和 ElementUI 做的,翻看 el-table 的时候发现一个属性,正好是用于实现该项功能的。

看说明,如果需要对表格内容进行无限滚动的操作,就用这个。那就是我们用 el-tablev-infinite-scroll就可实现这个内容。但是直接用,还是稍微会有一点麻烦,所以在这里推荐使用在 github发现的一个指令el-table-infinite-scroll 直接实现对 el-table的滚动加载。

此指令依赖于 element-ui@2.12.0,使用前请熟悉:

安装

npm install --save el-table-infinite-scroll

全局引入

import Vue from 'vue';
import elTableInfiniteScroll from 'el-table-infinite-scroll';

Vue.use(elTableInfiniteScroll);

局部引入

<script>
import elTableInfiniteScroll from 'el-table-infinite-scroll';
export default {
  directives: {
    'el-table-infinite-scroll': elTableInfiniteScroll
  }
}
</script>

组件中使用

<template>
  <el-table
    border
    height="400px"
    v-el-table-infinite-scroll="load"
    :data="tableData"
  >
    <el-table-column prop="date" label="日期" width="180"> </el-table-column>
    <el-table-column prop="name" label="姓名" width="180"> </el-table-column>
    <el-table-column prop="address" label="地址"> </el-table-column>
  </el-table>
</template>

<script>
import elTableInfiniteScroll from 'el-table-infinite-scroll';

const exampleData = new Array(10).fill({
  date: '2016-05-02',
  name: '王小虎',
  address: '上海市普陀区金沙江路 1518 弄'
});

export default {
  directives: {
    'el-table-infinite-scroll': elTableInfiniteScroll
  },
  data() {
    return {
      tableData: exampleData
    };
  },
  methods: {
    load() {
      this.$message.success('加载下一页');
      this.tableData = this.tableData.concat(exampleData);
    }
  }
};
</script>

<style scoped>
.el-table {
  width: 100%;
}
</style>

配置选项

参考 element-ui 官网 https://element.eleme.cn/#/zh-CN/component/infiniteScroll#attributes

用户体验改进

我们把上面的代码实现一遍,会看到我们很轻松的就实现了我们想要的滚动列表加载的效果。上面的代码中我们看到当我们一进入页面就会执行一遍load方法。但是想如果我们数据初始化的时候数据量很小,没有必要进行翻页查询,举个极端的例子比如我们只有一条数据,那我们这次的请求就是无效请求,是一种浪费用户时间,加重服务器负担的行为 ,是不可取的,所以我们需要有一个判断,判断数据是否需要在进来页面就执行load方法。

另外,对于后端接口的请求往往都是异步请求,返回数据是需要时间的,如果我们等待后台服务器返回数据这段时间内,反复触发了这个滚动加载的事件,特别是用户网络慢或者服务器负载大延长了服务器响应时间的时候,用户无聊的滚动着滚轮,大量的事件就会形成一个队列,依次向服务器发起请求,一个恶性的循环就形成了😨。另外测试人员对于这个问题也会测试的,他们就是拼命滑滚轮,玩死你(测试的同事看到了不要打我😷)。对于这个问题,我们同样需要设置一个条件,在请求后台数据的时候,我们不能进行数据请求的操作,另外为了交互的友好性,我们要提示用户数据正在加载中,请他们不要着急。

再就是如果当前我们请求的数据总量已经达到了后台数据量的总数,我们同样不能再触发后台的数据请求,然后给用户一个友好的提示,告诉他们数据已经加载完了,就不要拼命玩滚轮了。

综上我们需要改进的地方有三个:

  1. 判断页面初始化时是否要执行load方法

  2. 等待响应期间不能进行数据请求,并给出加载中的友好性提示

  3. 数据加载完成,禁止数据加载,并给出加载完成的友好性提示

el-table-infinite-scroll 这个指令的属性同饿了么 InfiniteScroll 无限滚动,饿了么这个指令中 infinite-scroll-disabled:禁止滚动加载,infinite-scroll-immediate:是否立即执行加载,来充满容器,正好对应我们这三个改进的地方。


指令我是全局配置,我把改进的代码线全部放到这里:

<template>
    <el-row :gutter="20">
        <el-col :span="8">滚动的列表</el-col>
        <el-col :span="15">
            <el-table
                    border
                    height="100%"
                    v-el-table-infinite-scroll="load"
                    infinite-scroll-immediate="first"
                    infinite-scroll-disabled="disabled"
                    :data="tableData"
            >
                <el-table-column prop="date" label="日期" width="180"> </el-table-column>
                <el-table-column prop="name" label="姓名" width="180"> </el-table-column>
                <el-table-column prop="address" label="地址"> </el-table-column>
                <div slot="append" style="text-align: center">
                    <span v-if="loading" class="prompt">--- 加载中 ---</span>
                    <span v-if="noMore" class="prompt">--- 没有更多了 ---</span>
                </div>
            </el-table>
        </el-col>
    </el-row>
</template>

<script>
    const exampleData = new Array(10).fill({
        date: '2016-05-02',
        name: '王小虎',
        address: '上海市普陀区金沙江路 1518 弄'
    });
    export default {
        name: "Table",
        data() {
            return {
                loading:false,
                dataCount:10,
                tableData: []
            };
        },
        computed:{
            first(){
                return this.dataCount > 10
            },
            noMore(){
                return this.tableData.length >= this.dataCount
            },
            disabled(){
                return this.loading || this.noMore
            }
        },
        methods: {
            load() {
                this.$message.success('加载下一页');
                this.loading = true;
                setTimeout(()=>{
                    this.tableData = this.tableData.concat(exampleData);
                    this.loading = false;
                },2000);
            }
        },
        mounted() {
            this.dataCount = 10;
            this.tableData = [...exampleData];
        }
    }
</script>

<style scoped>
    .prompt{
        display: inline-block;color: #d3dce6;margin: 10px
    }
</style>

这里根据 el-table-infinite-scroll 要求,给table加了height属性并设置为100%,让高度自适应。我们假设每次请求后台只返回10条数据,而10条数据无法充满容器。所以设置计算属性first,判断数据总量是否小于10,小于10时进入页面就不执行load方法,由于数据无法充满容器,其实这个指令相当于无效,列表就是正常的展示。通过 noMore 和 loading 控制 el-table 插槽中提示信息的显示。然后通过disabled计算属性通过loading || noMore来控制是否允许滚动加载,也就是这两个值要有一个是true就不让其滚动加载。好了一个滚动的列表就完成了。测试的时候可以通过改动dataCount值来看效果。

写在最后

眼看一个周又要过去,这是冠状疫情之后在北京禁足的第四个周。很想念上班的时光,今天看到集团公众号刊登的武汉同事的一句话:“好久没有一起为一个需求和方案跟工作中的小伙伴当面‘吵架’了”。然后晚上跟我的back-end partner煲了一个小时的电话粥。希望疫情快点过去,大家喜乐安康,平安复工!最后附上这个指令的具体方式,希望能和大家在前端道路的一起进步。

el-table-infinite-scroll 实现原理

相关文章

  • vue上拉加载List 列表

    介绍 Vant框架瀑布流滚动加载,用于展示长列表,当列表即将滚动到底部时,会触发事件并加载更多列表项。 在main...

  • 滚动加载的列表

    开始之前 今儿的项目又遇见一个不按套路出牌的设计:一个列表页,设计图上是不分页查询,后台给的接口是分页查询。跟产品...

  • 监测滚动到底部事件 react 自定义hook实现

    近期要实现一个滚动加载的列表组件,很明显可以通过绑定滚动事件来监听是否滚动到底部,每次滚动到底部的时候执行加载,然...

  • 预加载与智能预加载 (VIA)

    预加载与智能预加载(iOS) 网络与性能 预加载无限滚动列表Threshold惰性加载智能预加载 总结 前两次的分...

  • 费点时间

    一、移动端标签页(每个标签里都是一个长列表)滚动至顶切换 当第一个标签的长列表加载了很多数据,滚动条已经滚动到很底...

  • UIScrollView、UICollectionView、UI

    最近在做一个需求,统一管理列表页面的预加载和统计上报。简单点说,就是用户在滚动列表页时,当列表停止滚动时,请求当前...

  • 列表滚动的bitmap加载优化

    列表的滚动一般分为两种: 手指按下 -> 手指拖拽列表移动 -> 手指停止拖拽 -> 抬起手指 手指按下 -> 手...

  • ListView组件中 onEndReached 方法在滚动到距

    初次使用ListView,在写列表滚动到最底部自动加载使用到方法onEndReached,发现: ListVi...

  • 以asp.net 为后端,结合Vue.js和axios、vue-

    滚动加载或者说是无限加载,是一种当今非常流行的列表显示方式。当一个列表内容太长,通常需要使用分页的形式去展现出来,...

  • 关于SDWebImage加载gif动图导致内存爆炸的那些事

    关于SDWebImage加载gif动图导致内存爆炸的那些事SD加载gif比较方便,但是如果在列表这种滚动试图中有多...

网友评论

      本文标题:滚动加载的列表

      本文链接:https://www.haomeiwen.com/subject/urbjrhtx.html