列表跳转详情页缓存列表高度
介绍
今天要实现一个功能,从列表跳到详情页之后,再返回列表页,需要缓存当时的高度,并且刷新数据。
想一想也是比较简单,有两个想法:
- 当从列表跳到详情页前缓存现在的高度以及获取了多少条数据,从详情页回来的时候,需要重新获取数据线,然后跳到当时的高度。
- 直接在列表页去缓存当时的数据。在详情页操作过数据时,直接更新缓存的数据,返回时直接渲染缓存的数据,并跳到详情页所在的高度。
但是这两种方法都有缺陷,
- 第一种方法在返回的时候,要重新获取之前列表页的所有数据,如果数据量比较大,可能会有性能问题。
- 第二种方法虽然避免了重新获取数据,但存在其他设备修改了数据,无法立刻同步,数据的同步性无法及时保证。而且缓存数据如果过多,也会造成性能问题。
这边选了第一种方法来实现这个功能。
当然,第一种方法的缺陷也是可以弥补的,记录下当前页面的页码和每页的数据条数,只需要重新获取当前页的数据,而不是全部数据,从而减少了性能问题。这个之后看有时间再给填上吧。
实现
这里使用的是 uni-app 框架。主要是通过onHide和onShow生命周期函数与 uniapp页面栈 来实现的。
onHide生命周期函数的会在页面即将隐藏时触发,我们可以在这里缓存当前页面的高度和数据条数。
onShow生命周期函数会在页面显示时触发,我们可以在这里重新获取数据并跳转到之前的高度。
我这里是通过getCurrentPages()将数据缓存到了 uniapp 的页面栈中。
下面是示例代码,包括页面逻辑和封装的一个列表组件的核心代码 完整代码
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 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
| onShow(async () => { const page = getCurrentPages()[0] as { buffer?: { scrollTop: number; length: number; type: string }; }; if (page.buffer) { await itemListRef.value?.loadData(page.buffer.length); scrollTop.value = page.buffer.scrollTop; delete page.buffer; } else { itemListRef.value?.refresh(); } }); onHide(() => { getCurrentPages()[0].buffer = { scrollTop: itemListRef.value?.listScrollTop || 0, length: dataList.value?.length || 0, }; });
async function getList(isRefresh: boolean = true, load?: number) { if (loading.value) { return; } loading.value = true; hasMore.value = true; if (isRefresh) { page.value.pageNum = 1; } else { page.value.pageNum++; } if (load) { page.value.pageNum = Math.ceil(load / page.value.pageSize); }
const res = await getListData( load ? 1 : page.value.pageNum, load ? page.value.pageNum * page.value.pageSize : page.value.pageSize, load ? true : isRefresh, ); page.value.total = res.total; loading.value = false; hasMore.value = res.listLength < page.value.total; }
|
参考资料
uniapp-getcurrentpages
小程序列表跳转详情页面回来还是之前滚动的高度
关于本人
HaiYao的博客
Git主页