vxe-table 前端控制数据渲染(筛选 + 排序+ 分页)(2)
场景需求
- 场景需求,调用后端接口每次查询的数据,要累加到前端做存储,做统一控制
- 实现功能:前端分页查看,搜索筛选,排序
前置
- vxe-table 二次封装(筛选 + 排序 + 分页)(1)
- 基于vxe-table二次封装的基础上,增强前端数据渲染
- 分页查看,搜索筛选,排序的触发事件,返回的事件参数列表,前端进行数据过滤
实现思路
外层触发计算
列表数据增加
jsallData: { type: Array, default: () => [] },
内层触发计算
1、过滤filter
jsfileterData () { let data = [] data = this.filterList.length > 0 ? this.filterList.reduce((pre, next) => { // 筛选是且关系,reduce逐层过滤 // 过滤列表,依次对数据进行过滤 // pre 做为过滤之后的数据返回 // next 做为每一次的过滤条件 return pre.filter((item) => // item[next.field] 是当前行的数据 // next.datas[0] 是第一条过滤条件 filterValue(item[next.field], next.datas ? next.datas[0] : next) ) }, this.allData) : this.allData return data },- 过滤数据分三大类型:字符串、数字、日期(时间)
jsexport function filterValue(n, filterData) { switch (filterData.valueType) { case 'string': { return filterStringValue(n, filterData) } case 'number': { return filterNumberValue(n, filterData) } case 'date': case 'time': case 'datetime': { return filterDateValue(n, filterData, filterData.valueType) } default: } return false }- 以字符串为例,根据不同的过滤条件,进行不同的数据过滤
jsexport function filterStringValue(n, filterData) { switch (filterData.condition) { case 'eq': { // return (!isEmpty(n) && filterData.values?.some((item) => String(item) === String(n))) ?? false return (!isEmpty(n) && String(filterData.value) === String(n)) ?? false } case 'include': { return !isEmpty(n) && String(n).includes(String(filterData.value)) } case 'isEmpty': { return isEmpty(n) } case 'isNotEmpty': { return !isEmpty(n) } case 'in': { return !isEmpty(n) && filterData.values.includes(String(n)) } default: } return false }2、排序sort
jssortData () { const data = this.fileterData if (this.sortList.length > 0) { data.sort((a, b) => { // 排序条件多条:依次对排序列表进行过滤 // 比如有两个字段,一个正序,一个倒序 // 先以第一个排序条件优先,!==0则大小已定,===0对应数值相同,则进行下一个排序条件,进行排序 // 参考后端排序算法 for (const list of this.sortList) { const res = sortValue(a, b, list) if (res !== 0) { return res } } return 0 }) } return data },- 排序数据也分三大类型:字符串、数字、日期(时间)
jsexport const sortValue = (a, b, val) => { const dataA = a[val.field] const dataB = b[val.field] const order = val.order const valueType = getColumnFilterValueType(val.column) switch (valueType) { case 'string': { return sortString(String(dataA), String(dataB), order) } case 'number': { return sortNumber(dataA, dataB, order) } case 'date': case 'time': case 'datetime': { return sortDateTime(dataA, dataB, order) } default: { return 0 } } }- 以数字为例,根据不同的排序条件进行排序
jsconst sortNumber = (dataA, dataB, order) => { // 数字比大小 return order === 'asc' ? dataA - dataB : dataB - dataA }3、分页page
jscurrentData () { return this.sortData.slice( (this.page.currentPage - 1) * this.page.pageSize, this.page.currentPage * this.page.pageSize ) },
注意
- 关于复选数据重复的问题:
- 数据通过查询,增量累加,不存在单独减少操作,此时不需要考虑复选数据更新;
- 数据执行操作成功,会对数据重置或删除,此时要更新复选的数据,设置为空;