需求点分析
图片列表滚动触底的逻辑
- 将图片id组成的一维数组根据指定个数一组拆分为二维数组
- 定义一个索引初始值为-1,图片列表滚动触底,索引值自增,然后将拆分好的图片id二位数组对应的数据读出来放到图片id的数组
- 图片根据列表新增的id取读取每张图片的url,并将读取到的url添加到图片列表中
图片预览所有的数据
- 图片的个数可能会有很多,不能采用所有的图片都加载完成才开始渲染,所以采用 递归的方式,加载完当前图片在加载下一张图片
技术点基础
@scroll事件
- scroll 事件用于给元素绑定滚动事件,当然也可以使用 原生js的 addEventListener(“scroll”,fn,false) 实现
滚动触底的三要素
- scrollTop 元素垂直滚动出窗口的距离
- clientHeight 元素的内部宽度
- scrollHeight 元素内容的高度(包含可视高度和滚动出去的高度)
- scrollHeight = scrollTop + clientHeight
- 当 scrollHeight + 50 < scrollTop + clientHeight 时触发触底的逻辑
promise.all
- promise.all 可以理解为同时处理多个promise的异步请求
- promise.all的入参是一个由多个promise组成的数组
- promise.all的回参是有传入promise数组中的每个返回值组成的数组
- 返回值顺序与如参数顺序保持一致
递归处理数据
- 递归是在满足条件的情况下自己调用自己
- 在不确定数据个数的情况下,可采用递归处理
代码实现
滚动触底加载
html
<div class="list" @scroll="loadMoreImgFn"></div>
loadMoreImgFn(ev) {
const self = this;
if (
ev.srcElement.scrollTop + ev.srcElement.clientHeight >
ev.srcElement.scrollHeight - 50
) {
// 触底的业务逻辑
self.handleImgData(currentIds);
}
}
将根据id请求图片地址的代码封装成函数
- 将根据图片id请求图片url的ajax氢气封装成 promise,
- 将需要的数据作为函数的返回值
getImgFileById(ele) {
console.log("ele==0", ele);
return new Promise((resolve, reject) => {
// 获取图片信息的业务逻辑
// 将数据resolve出去
let data = {}
resolve({
data
});
});
}
promise.all处理图片列表数据
- 循环 图片id数组,调用 上边的 getImgFileById 拿到 promise返回的对象,并添加到数组中
- 使用promise.all 处理上述数组
- 拿到res 进行相关逻辑处理,得到想要的数据格式
let imgResList = [];
let promiseList = [];
imgList.forEach(async (ele, index) => {
let imgP: any = this.getImgFileById(ele);
promiseList.push(imgP);
});
Promise.all(promiseList).then((res) => {
// 拿到res 进行相关逻辑处理,得到想要的数据格式
let item = res//相关处理逻辑 此处省略
imgResList.push(item)
})
根据图片id数组,获取图片列表数据,进行渲染
技术点分析
不采用promise.all原因
- promise.all 是所有的promise都返返回了结果,才会返回所有的值
- 此处图片太多可能有几十张,会等很久才出现图片
- 因此采用一张图片一张图片渲染的模式,技术点上采用递归的模式
代码实现
每张图片读取逻辑
// 定义currentFileId 变量
// 定义idList 图片id数组
// 定义 showFiles 渲染图片变量
async getImgFileByIdSingle(idList) {
this.currentFileId++
// 获取图片信息的业务逻辑
// 将数据resolve出去
let fileId = idList[this.currentFileId];
let itemData: any = await this.getImgFileById(fileId);
this.showFiles.push(itemData)
if (this.currentFileId < idList.length) {
this.getImgFileByIdSingle(idList);
}
}