后端: 数据都给你了,分页、排序、筛选你看着办吧。。。

语言: CN / TW / HK

theme: Chinese-red

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第1天,点击查看活动详情

前言

后端一口气返回了全部的数据,不多不少,也就十几万条数据,问:前端应该怎么办?

某个项目碰到了这个问题,一般十几万条数据不可能一口气给到前端,一是请求时间会比较长,用户体验不好;二是前端不可能一次性显示这么多数据,通常都需要分页显示,保障页面的流畅,所以只需要获取一部分显示的数据就够了。

但真碰上了,只能想办法解决了,肯定是不可能一次性将全部数据显示出来,必须进行分页处理。

关键在于,前端怎么将这些数据进行分页排序筛选

以下是个人的思路,希望大佬多多指点。

技术栈

Vue

前置工作

首先,使用个数组存储数据,每个数组储存的数据也许相同,也许不同,各自有各自的用途,如下:
1. originDataList: 存储全部原始数据的数组; 2. originSortDataList: 该数组的数据与 originDataList 一致,但是该数组经过了排序处理,用于筛选操作; 3. showAllDataList: 全部可展示的数据,该数组是经过排序筛选之后,可用于展示的全部数据的合集; 4. showDataList: 真正渲染到页面上数据集合,即 showAllDataList 的分页数据;

分页

分页处理是最简单的,根据上面定义的四个数组来看,就是从 showAllDataList 中,根据 pageSize(页面单次显示的数据)和 pageNumber(页码),取出指定范围内的数据,赋值给 showDataList 渲染到页面上即可,主要代码如下: js function getShowDataList () { // 确定起始索引 const startIndex = (this.pageSize - 1) * this.pageNumber this.showDataList = this.showAllDataList.slice(startIndex, startIndex + this.pageNumber) }

因为真正渲染到页面上的数据,都是从 showAllDataList 中取出的,所以不管是排序还是筛选,最终都是对 showAllDataList 进行修改,然后通过分页的函数进行取值渲染。

排序

排序也不难,无非就是对用户指定的字段进行升序或者降序即可。

应用到项目中,就是对 showAllDataList 进行排序处理,根据排序要求,对 showAllDataList 进行相应的处理。

大概代码如下:

js /** * 排序 * @param { String } key 需要排序的属性名称 * @param { 'asc' | 'desc' | '' } order 排序方式 */ function sortList (key, order) { // 如果 order 为 '',即不指定排序,重置 showAllDataList if (!order) { // 注意:至少需要进行一层浅拷贝,不然会更改 原始数据的数组 this.showAllDataList = [...this.originDataList] } else { // 排序处理 order === 'asc' ? this.showAllDataList.sort((itemA, itemB) => itemA[key] > itemB[key] ? 1 : -1) : this.showAllDataList.sort((itemA, itemB) => itemA[key] > itemB[key] ? -1 : 1) } // 更改渲染数据 this.getShowDataList() } 至此,基本实现了排序的功能,当然,具体的排序实现因人而异,不再赘述。

originSortDataList 这个数组需要经过排序处理,供筛选功能使用,所以对 showAllDataList 进行排序的同时,也需要对 originSortDataList 进行排序。

加上 originSortDataList 之后,代码如下: js /** * 排序 * @param { String } key 需要排序的属性名称 * @param { 'asc' | 'desc' | '' } order 排序方式 */ function sortList (key, order) { // 如果 order 为 '',既不指定排序,重置 showAllDataList if (!order) { this.showAllDataList = [...this.originDataList] this.originSortDataList = [...this.originDataList] } else { // 排序处理 order === 'asc' ? this.showAllDataList.sort((itemA, itemB) => itemA[key] > itemB[key] ? 1 : -1) : this.showAllDataList.sort((itemA, itemB) => itemA[key] > itemB[key] ? -1 : 1) order === 'asc' ? this.originSortDataList.sort((itemA, itemB) => itemA[key] > itemB[key] ? 1 : -1) : this.originSortDataList.sort((itemA, itemB) => itemA[key] > itemB[key] ? -1 : 1) } // 更改渲染数据 this.getShowDataList() }

筛选

经过上面的处理,筛选就变得十分简单,直接从 originSortDataList 中挑选出符合筛选条件的数据,组成新的数组,赋值给 showAllDataList 即可。

主要代码如下: js /** * 筛选 * @param { String } key 需要排序的属性名称 * @param { Number | String | Boolean } value 筛选值 */ function filterList (key, value) { // 不存在 value,则不进行任何筛选操作 if (value === '') { // 浅拷贝,避免对 showAllDataList 进行修改会影响到 originSortDataList this.showAllDataList = [...this.originSortDataList] } else { // 筛选的数据从 originSortDataList 中取出 this.showAllDataList = this.originSortDataList.filter(item => { // 根据实际项目进行判断筛选 }) } // 更改渲染数据 this.getShowDataList() }

为什么不直接从 originDataList 或者 showAllDataList 进行筛选? 1. 因为 originDataList 的数据不会改变,因为排序的重置功能需要原始数据才能实现;而如果使用originDataList,当排序筛选同时执行时,筛选originDataList取值,则排序会失效。 2. showAllDataList 本身不一定包含着全部的数据,它的功能就是存储所有可展示的数据,筛选过后,如果存在某些数据不符合要求,则不会存储在 showAllDataList 中,如果使用 showAllDataList 进行筛选,会有遗漏。