关于 select 分页获取数据优化

项目中,有个 select 下拉选择做成了分页的形式,就是默认请求第一页的数据,然后当用户下拉到底部的时候,在重新请求一个接口,页码 +1。

这个做法有两个难点,第一个难点是你需要知道用户何时滚动到底部,并且调用接口获取数据;第二个难点是,比如说用户选择了第三页的某个 option,但是当你复原数据的时候,默认只请求第一页的数据,你直接赋值的话,会把用户选择第三页的值原封不动的显示在页面上。

首先是如何知道用户滚动到底部,因为使用的是 Vue + element-ui,所以可以使用 Vue 提供的自定义指令来监听滚动条,然后判断高度。代码如下:

// template
<el-select  v-model="form.test" v-loadmore="someFunction" ></el-select>

// script
directives: {
	loadmore: {
		bind(el, binding) {
			const dom = el.querySelector(".el-select-dropdown .el-select-dropdown__wrap")
			dom.addEventListener("scroll", () => {
				let different = dom.scrollHeight - dom.scrollTop <= dom.clientHeight
				if (different) {
					binding.value()
				}
			})
		},
	},
}

methods: {
	someFunction() {
		// 获取接口
		// 假设接口获取到的数据为 axiosInfo 
		
		//数据组合
		// 假设当前的 v-for 为 testList
		this.testList = [...this.testList, ...axiosInfo]
	}
}

上面数据获取到了,之后就是第二个问题。一般来说分页接口都有 total 来表示数据总共的条数,以及 page 表示当前的页码,那么在保存数据的时候,可以顺便把当前请求的最后页码保存起来,下次再请求的时候,可以使用 while 循环来判断。

let userSavePage = 3  // 假设通过接口获取到用户选择的最后一页为 3
let currentPage = 1  // 当前页数,默认为 1

while(currentPage < userSavePage) {
	currentPage++
	getAxiosFun() // 获取数据接口
}

这样就解决了这个问题,但是有一种情况可以优化一下,假设用户选择了第三页的数据,当前的 currentPage 为 3,当用户取消选择了第三页的数据,又选择了第一页的数据,那么 currentPgae 还是 3,保存的时候页码还是 3,你下次请求还是请求 3 次,所以这就造成了一种资源浪费,不仅多了 2 次 http 请求,还加大了页面渲染的压力。

那么优化的方法思路是:

首先是需要根据用户所选择的数据,获取到数据里所在页码的最大值,而不是用户选择的最后一个值,因为如果用户选择了第三页的某个值,当前获取到的页码是 3,如果用户选择了第四页的值,当前获取到的页码是 4,用户继续选择第一页的值,那么当前获取到的页码是 1,如果你直接根据最后一个值,那么获取到的页数是 1,那么就不对了。

所以,因为依次遍历用户选择的每一项,找到所在 index 最大的那个值,然后计算出页码,进行保存。

代理逻辑是:

  • 使用forEach依次遍历所选数据
  • 使用 findIndex 找到 index 并保存在一个列表里
  • 根据 Math.max(...xxx) 找到最大的 index
  • 根据 size 计算出页码(一般是10),Math.ceil(index/size)

这里有个隐藏的 bug,就是 size 是不固定的,如果你保存的时候,size 比较大,那么相对的保存的 page 就较小,但是当你把 size 变小的时候,那么真实获取的其实 page 应该变大,所以以上优化应该在 size 固定的情况下使用

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值