列表内容过多卡顿?有索引栏如何实现滚动加载?

👓写在前面

很多小伙伴可能在开发业务中会遇到这种问题,数据列表过多,造成dom一次性渲染卡顿,本文主要介绍滚动加载,实现在有索引栏的列表中使用滚动加载的方法。

本文技术栈使用的是vue2+vant2,其他框架组件库也都有相似之处,可以做个参考

🥇Vant自带组件滚动加载

vant组件库已经提供了一种滚动加载的方法,参考链接

List组件

image-20240731101141490

List 组件通过 loadingfinished 两个变量控制加载状态,当组件滚动到底部时,会触发 load 事件并将 loading 设置成 true。此时可以发起异步操作并更新数据,数据更新完毕后,将 loading 设置成 false 即可。若数据已全部加载完毕,则直接将 finished 设置成 true 即可。

📋这里需要注意一个点是,当完全加载完毕时,其load事件不会再触发,所以再切换数据或者其他不会导致组件重新渲染的操作时,这个load事件也不会触发,这个时候需要进行下面操作

//把完成状态改为未完成
this.finished = false
// 切换时触发是否滑到底部检查
this.$refs.lists.check()

check方法介绍

通过 ref 可以获取到 List 实例并调用实例方法,详见组件实例方法

方法名说明参数返回值
check检查当前的滚动位置,若已滚动至底部,则会触发 load 事件
🍳索引栏列表实现滚动加载

vant组件库中还有一个indexBar索引栏组件

image-20240731103431814

可以根据右侧索引栏点击跳转到对应列表,而且这种就不能简单的靠List组件实现滚动加载了

实现

可以主要分为下面几步

  1. 在indexBar外包裹List组件,先实现普通的滚动加载
  2. 添加索引栏绑定事件
  3. 判断点击索引是否存在,进行调整还是添加数据

第一步不用过多赘述,实现比较简单,直接看第二步

添加索引栏绑定事件

添加绑定事件是因为vant索引栏有一个缺陷,如何对应的索引列表没有对应的值,索引栏点击没有效果,所以这个会影响咱们后续操作,这里是采用的原生绑定事件

		// 根据样式获取其元素
		const boxes = document.querySelectorAll(".van-index-bar__index")
		boxes.forEach((box) => {
			box.addEventListener("click", function handleClick(event) {
				//获取当前点击索引
				_this.enum = box.innerHTML

			})
		})

判断加载数据

这个时候需要判断点击的索引是否存在已经加载的数据中,如果存在会自动跳转,不存在则调用加载数据的方法,同时IndexBar组件库有scrollTo方法,可以跳到对应索引,我这里判断*是跳到第一个

		//全部字母列表点击事件
		handleAllLetterClick() {
			let _this = this;
			//判断选中的字母是否在已经加载的数组内
			let index = _this.list.findIndex((element) => element.capitalInitia == 				this.enum);
			//已存在 会自动跳转
			if (index != -1) {
				return
			} else if (this.enum == '*') {
				// 点击*回到第一个字母
				this.$refs.IndexBar.scrollTo(this.content[0].capitalInitia);
			}else {
				_this.onLoad('jump');
			}
		},

onLoad方法,这里是把数据分成两部分,list是展示数据,content是全部数据,一次加载五个数组,如果点击索引没有获取到会递归调用,直至获取到,或数据加载完毕

📃注意点:我这里是一次获取所有数据然后在前端处理,另一种方法可以采用分页获取方法,在此方法中异步调用,看与后端人员如何定义了

	onLoad(type) {
			let add = 0
			//此步可以用异步调用替换
			for (let i = this.list.length; i < this.content.length; i++) {
				this.list.push(this.content[i])
				add++
				if (this.content.length == this.list.length) {
					// 数据全部加载完成
					this.finished = true
				}
				if (add >= 5) {
					// 加载状态结束
					this.loading = false
					break
				}
			}
			let index = this.list.findIndex((element) => element.capitalInitia ==this.enum);
			if (index != -1) {
				//点击才跳转
				if (type == 'jump') {
					this.$refs.IndexBar.scrollTo(this.enum);
				}
				//已存在
			} else if (this.content.length > this.list.length) {
				this.onLoad();
			}
		},
🎨总结

实现原理其实就是一点一点加入,具体怎么加入,什么时候加入,是实现这个功能的主要点,其他组件库都可以按照类似方法进行实现,欢迎交流!

  • 5
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

时雨.`

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值