• vue3解决elementPlus table组件数据量大时的卡顿问题


    项目框架

    vue3+ts+elementPlus

    项目场景

    根据产品需求,需要在弹窗中使用elementPlus的table组件。数据量少的时候没有问题,当数据条数超过30条时,会有卡顿现象。于是使用了下拉加载分页数据解决当前问题

    最终效果

    请添加图片描述

    主要代码展示

    弹窗组件中table组件代码
    在这里插入图片描述

    图中标出的是给table组件绑定了滚动监听指令:vTablescroll,因为组件本身没有提供监听滚动的事件;
    main.ts中全局绑定自定义指令:.el-scrollbar_wrap 是table 的内容滚动的类名,无需自定义。

    import App from '/App.vue'
    const app = createApp(App)
    app.directive( 'vTablescroll', {
    	mounted(el: Element,binding) {
    		const selectwrap = el.querySelector('.el-scrollbar_wrap')
    	if (selectWrap == null) return
    	selectwrap.scrollFn = function () {
    	const sign = 0
    	const scrollDistance =
    		this.scrollHeight - this.scrollTop - this.clientHeight
    		if ( scrollDistance <= sign) {
    		binding.value()
    		}
    	}
    	selectwrap.addEventListener( 'scroll', selectwrap.scrollFn)
    },
    	unmounted(el: Element){
    	const selectwrap = el.querySelector('.el-scrollbar_wrap')
    	if (selectwrap == null) return
    	selectwrap. removeEventListener( 'scroll' , selectwrap.scrollFn)
    	selectwrap.scrollFn = null
     }
    })
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    绑定自定义指令后:在组件中使用: v-vTablescroll=“需要执行的分页逻辑函数” 此处用loadMore 为例:(类型我已经忽略)

    /**
    * 下拉动态加载逻辑
    */
    /*下拉分页后的数据*/
    const finalTableData = ref()
    /*数据中转变量*/
    const transferTableData = ref()
    /*  props.layerListData 是从外部传给table组件使用的原始数据,用transferTableData 中转一下 */
    transferTableData.value = props.layerListData
    
    let tempTableLayerData = []
    let pageNum = 0
    function loadMore(){
    	const layerList = transferTableData.value
    	// 数据总量
    	const total = layerList.length
    	// 每页条数
    	const pageSize = 10
    	// 如果加载结束就返回
    	if (pageNum * pagesize > total) return
    	// 计算每页的数据
    	const OnePageData = layerList.slice(pageNum * pagesize, (pageNum + 1)* pagesize)
    	// 每下拉一页之后merge到前面的数据中
    	const mergeData = tempTableLayerData.concat(OnePageData)
    	tempTableLayerData = mergeData
    	//形成最后的数据给table组件使用
    	finalTableData.value = tempTableLayerData
    	pageNum++
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    到这里主要的逻辑就差不多了,但是还有一些小拓展供大家参考:重置数据 刷新当前数据或者切换成搜索当前数据的时候会需要

    /**
    * 重置数据逻辑
    */
    /**
    *重置数据*/
    function resetLayerData() {
    	tempTableLayerData = []
    	finalTableData.value= []
    	transferTableData.value = []
    	pageNum = 0
    	//重置完数据之后,执行loadmore()数据会回到第一页的状态
    	transferTableData.value = props.layerListData
    	loadMore()
    	//这个时候表格需要滚动回第一行
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    /**
    *聚焦到列表第一行*/
    function focusFirstRow (){
    // singleTableRef 是table的ref 对象
    	if (singleTableRef.value) {
    	nextTick(()=>{
    	// 滚第一行
    	singleTableRef.value.setScrollTop(o)}
    	// 让第一行是选中的样式,可以看一下文档组件中的用法
    	singleTableRef.value!.setCurrentRow(finalTableData.value[0])}
    }
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    往往数据多的场景都会需要搜索功能(只是前端实现)效果如下:

    请添加图片描述

    搜索的逻辑如下

    **
    * 按图层名字搜索图层数据
    */
    function handleFilterData (){
    	/*重置数据之后进行搜索*/
    	tempTableLayerData = []
    	finalTableData.value = [ ]
    	transferTableData.value = []
    	pageNum = 0
    	/*搜索数据*/
    	const searchRes = props.layerListData.filter(data =>{
    		return (
    		! searchVal.value ||
    		data.attrs.name.toLowerCase().includes( searchVal.value.toLowerCase())
    		)
    	})
    	/*搜索结果按照名称的长短排序*/
    	if ( searchVal.value) {
    	// 有值就进行排序
    		transferTableData.value = searchRes.sort(
    		(a, b) =>a.attrs.name.length - b.attrs.name.length)
    	}else {
    	// 无值就返回原来的数据
    		transferTableData.value = searchRes
    	}
    	nextTick(() =>{
    	// 搜索完回滚到顶部
    	singleTableRef.value.setScrollTop(O)
    	})
    	//在执行第一个分页的加载
    	loadMore()
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    到这里基本就结束了,还有其他的一些细节就不再展示了,vue2逻辑也大差不差,如果有什么不懂的地方请留言,我会进行解答~ 对您有用的话记得三连哦~3q

  • 相关阅读:
    【多媒体技术与实践】课堂习题汇总(Chp1~Chp3)
    SpringBoot3 正式发布:有哪些新玩法?
    备战数学建模30-回归分析2
    2024.06.16 刷题日记
    SpringBoot--WEB技术基础
    【COMP329 LEC4 Locomotion and Kinematics】
    蓝牙BLE调试关于NRF connect相关信息分析
    编译安装Linux内核
    Review Intro to NoSQL
    线程池相关总结
  • 原文地址:https://blog.csdn.net/TIAN20121221/article/details/127460249