起源
最近在做人事管理的项目,加了个新需求,可以指派下一个审核的人,心里想:这不是调两个接口,一个查询用户。一个指派操作。
这么简单的东西还不是分分钟搞定。做完该做的交互,等到调测试接口的时候...... ,好家伙!这....4000多条数据
这浏览器不得卡的飞起。事实证明判断的没错。每次唤起picker的时候界面都卡顿一下。
问题大纲
-
因为此操作是在列表中,对单一项进行操作。每次进行指派的时候都会调用查询用户接口(显然是不合理的)
解决方案
只需要把请求的数据拿回来的时候存在电脑上就ok啦,因项目没有采用vuex(也不想再加了)。所以我们可以使用浏览器的本地缓存。
当本地缓存的数据不存在的时候,调用函数,否则直接赋值即可
代码上
if(uni.getStorageSync('allUsers')){ this.workGroupeOptions =this.group(JSON.parse(uni.getStorageSync('allUsers')),100)[0] this.searchOption =JSON.parse(uni.getStorageSync('allUsers')) }else{ this.getUserList() }
-
数据绑定在piker上的时候因数据项太多,生成的节点数太多,导致的卡顿。(要么后端做分页,要么只有自己撸,公司的后端抱着多一事不如少一事的心态,显然不愿意搞,那就前端处理)
解决方案
既然数据太多的话那么我们可以把数据分成几个批次依次加入到picker绑定的数据源中。
理想的情况下当picker上滚动到倒数第10项左右的时候添加数据进去
翻阅了一下uniapp的官网发现picker有个滚动时,触发的change函数,并且向外部暴露了当前的每项的下标
到现在为止,已经找到解决的办法
代码上
分割数据的函数
第一个参数是要分割的数组对象,第二个分割的每一项里面包含多少项数据
group(array, subGroupLength) {
let index = 0;
let newArray = [];
while(index < array.length) {
newArray.push(array.slice(index, index += subGroupLength));
}
return newArray;
},
滚动事件的函数
这里新增了个num变量,是为了计算出已经新增到了第几项数据,
到了最后num和分割出来的数据长度一致时,那么将不再新增数据
scrollChange(e){
let allUser = this.group(JSON.parse(uni.getStorageSync('allUsers')), 100)
let num =0
if(e.detail.value[0]==this.workGroupeOptions.length-10){
num++
if(num!=allUser.length){
allUser[num].forEach(item=>{
this.workGroupeOptions.push(item)
})
}
}
结语
这个功能目前有个问题,就是当用户一直滚动到最下面的时候,界面依然会导致卡顿。只不过是一个循序渐进的过程而已。有时间的话可以改造成picker里数据应该只包含我们分割出来的数据里面的三项。