记录实现el-table列表的无限滚动(InfiniteScroll)--使用原生Scroll

        由于接收到要求,项目由vue2切换成vue3,要前台列表使用无限滚动展示数据,我在查阅资料后发现原来官方推荐的方法是vue-infinite-scroll这个现在已经不在维护的插件,虽然vue-infinite-scroll确实挺好的,但就是不支持vue3,所以我使用的是原生的scroll标签实现的。相当于滚动加载下一页的数据。

 上代码:

import { ref } from 'vue'

我自己做了一个简单的列表

<!-- 数据表格 -->
	<el-table ref="businessTable" :data="sourceBusiness.list" style="width: 100%; max-height: 400px; overflow-y: auto" @scroll.enter="handleScroll">
		<el-table-column prop="businessCode" label="业务属性代码" />
		<el-table-column prop="businessName" label="分类名称" />
		<el-table-column prop="describes" label="描述" />
		<el-table-column label="操作">
			<template #default="{ row }">
				<el-button type="primary" @click="editBusiness(row)">编辑</el-button>
				<el-button type="danger" @click="deleteBusiness(row)">删除</el-button>
			</template>
		</el-table-column>
	</el-table>
data() {
	return {
		loading: false,
        scrollTimer: null,
        showLoadMoreButton: true,  //是否显示加载更多数据
        scrollPosition: 0,  //记录滚动条位置
		businessRequest: {
			businessCode: '',
			businessName: '',
			pageNum: 1,
			pageSize: 10
		},
		sourceBusiness: {
		list: [],
		total: 0
		},
        // 其他数据信息...
     }
created() { 
    this.loadData()
	},

methods:

    //滚动事件
    handleScroll() {
      //这是使用setTimeOut函数来延迟执行,以便在滚动表格的时候节省资源和优化性能
      //设置一个定时器scrollTimer,判断如果之前设置过定时器会清除之前的定时器,以免多次触发滚动事件
      if (this.scrollTimer) {
        clearTimeout(this.scrollTimer);
      }
      //设置定时器scrollTimer延迟200毫秒后执行回调函数
      this.scrollTimer = setTimeout(() => {
        const tableEl = this.$refs.businessTable.$el    //表格的DOM元素
        const scrollContainerHeight = tableEl.clientHeight  //获取表格容器的高度,即当前可见区域的高度
        const scrollContentHeight = tableEl.scrollHeight  //获取表格内容的高度,即所有行的高度
        const scrollTop = tableEl.scrollTop  //获取表格容器滚动的距离,即当前可见区域顶部距离表格顶部的距离

        //判断是否到达底部并且当前没有正在加载更多数据,如果是,则执行方法loadMoreData()
        if (scrollTop + scrollContentHeight >= scrollContainerHeight && !this.loading) {
          this.loadMoreData()
        }
        //将当前滚动位置保存到组件实例的scrollPosition中,以便下次执行定时器能够正确判断滚动事件
        this.scrollPosition = scrollTop
      },200)
    },
    //这个方法用于从后端加载数据并将其添加到当前显示数据的末尾
    loadData() {
      //表示正在加载数据
      this.loading = true
      //根据currentPage 和 pageSize 从后端加载数据
      //发起请求,更新businessData
      useBusinessApi(this.businessRequest).then(res => {
        //将获取到的数据添加到当前已经显示的数据末尾,这里使用concat函数将两个数据合并
        this.sourceBusiness.list = this.sourceBusiness.list.concat(res.data.list)
        console.log(this.sourceBusiness.total)
        //表示数据加载完成
        this.loading = false
        //使用$nextTick函数延迟执行一段回调函数
        this.$nextTick(() => {
          //回复滚动位置
          const tableEl = this.$refs.businessTable.$el
          //将表格的滚动位置设置为新的scrollPosition属性,以保持在加载数据时的滚动位置保持不变
          tableEl.scrollTop = this.scrollPosition
        })
      })
      .catch(error => {
        //发生错误,控制台打印错误信息,并将 loading 属性设置为 false,表示数据加载完成
        console.error(error)
        this.loading = false
      })
    },
    //滚动到底部时加载更多数据    
    loadMoreData() {
      //将请求类的页码的pageNum加一,以获取下一页的数据
      this.businessRequest.pageNum++
      //加载数据到后端,以实现无限滚动效果
      this.loadData()
    },

后端是使用MyBatisPlus实现的普通的分页列表:

    @PostMapping("/page")
    @Operation(summary = "分页")
    public Result<PageResult<SourceBusiness>> page(@RequestBody BusinessRequest businessRequest){
        PageResult<SourceBusiness> result = businessService.page(businessRequest);
        return Result.ok(result);
    }

展示效果:

 

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值