vxe-table 二次封装(筛选 + 排序 + 分页)(1)
场景需求
- 在vxe-table的基础上,增加对排序和筛选的配置
- 同时增加对分页的支持
- 技术栈:vue2 + vxe-table@3.8.22
基本调研
- 查看v3版本文档
注意:本次使用 v3.8版本,现在已经不维护了(只做封装思路参考)
一些demo的代码实现:
- 本地数据,简单筛查:https://vxetable.cn/v3.8/#/table/base/filter
- 本地数据,复杂筛选:https://vxetable.cn/v3.8/#/table/advanced/manualFilter
- 手动筛选:调用 setFilter 和 updateData 方法来处理复杂场景
- 修改筛选条件
- 展示、关闭筛选面板
- 清除所有筛选条件
- 设置筛选渲染:https://vxetable.cn/v3.8/#/table/renderer/filter
- 本地数据,分页:https://vxetable.cn/v3.8/#/table/advanced/page
- 数据代理,分页:https://vxetable.cn/v3.8/#/table/grid/pageProxy
常用事件
js<vxe @checkbox-change="checkboxChange" @checkbox-all="checkboxChange" ></vxe>常用方法
js// 设置选中 setCheckboxRow(rows, checked) setAllCheckboxRow(checked) // 清除选中 clearCheckboxRow() clearCheckboxReserve() // 获取 getCheckboxRecords() getCheckboxReserveRecords()常用配置
html<!-- 保持勾选记录,数据更新(翻页后,再翻回来) --> <vxe :row-config="{ keyField: 'id', }" :checkbox-config="{ reserve: true }" ></vxe>
实现思路
排序配置
排序配置比较简单
- 配置:
- 在 VxeColumn 组件的 sortable 设置为true
<VxeColumn :sortable="true"></VxeColumn>
- 在 VxeColumn 组件的 sortable 设置为true
- 触发:
- 在 VxeTable 组件上,监听 sort-change 事件,获取排序参数数据
<VxeTable @sort-change="sortChange> - 存在多列触发排序的情况,排序参数数据返回是多条,其中排序类型 order:
正序 asc倒序 desc
- 在 VxeTable 组件上,监听 sort-change 事件,获取排序参数数据
筛选配置
筛选配置相对复杂
配置1:注册筛选组件
- 1、需要
VXETable.renderer.add(BaseFilterRenderName, filterConfig)注册一个筛选配置
js
VxeTablePlus.install = function install(Vue) {
VXETable.renderer.add(BaseFilterRenderName, filterConfig)
Vue.component(VxeTablePlus.name, VxeTablePlus)
}- 2、filterConfig如下
jsx
export const filterConfig = {
showFilterFooter: false,
renderFilter(h, { attrs, props }, params) {
// 注冊筛选组件
return <TableFilter {...{ attrs, props }} scope={params} />
},
// 重置数据方法
filterResetMethod({ column, options }) {
for (const option of options) {
option.data = getColumnDefaultFilterData(column)
}
},
// 筛选方法
filterMethod({ cellValue, option }) {
// 这里的注意点:
// 如果设置为remote = true,$panel.confirmFilter()调用时,这里不会触发
return filterValue(cellValue, option.data)
},
}3、TableFilter 筛选组件如何构造
筛选组件数据来源
js// 配置数据 const { $table, column } = this.scope this.option = column.filters[0]?.data ? column.filters[0] : { data: getColumnDefaultFilterData(column), }筛选选项控制(核心点)
- 确认筛选数据的类型 option.data.valueType 包括:数字、字符串、日期时间类(日期、时间、日期时间)
- 根据筛选数据的类型,获取对应控制下拉对比条件 condition
jsconst conditions = defaultConditions[this.valueType ?? 'default'] ?? []- 根据筛选数据的类型,渲染对应组件
jsfilterComponent() { if (this.isCustomOptions) { return TrTableFilterCustom } switch (this.valueType) { case 'date': { return TrTableFilterDate } case 'time': { return TrTableFilterTime } case 'datetime': { return TrTableFilterDateTime } case 'number': { return TrTableFilterNumber } default: { return TrTableFilterDefault } } },自定义了筛选按钮的逻辑
jsasync handleFilter(evt) { try { await this.$refs.filter?.validate() const { $panel } = this.scope // 调用 vxe-table 筛选api,触发 vxe-table @filter-change事件 $panel.changeOption(evt, true, this.option) $panel.confirmFilter() } catch (e) { console.log(e) } },- 自定义重置按钮的逻辑
jshandleReset() { const { $panel } = this.scope // 调用 vxe-table 重置api $panel.resetFilter() },
配置2:使用筛选组件
- 1、在 VxeColumn组件 上配置 filter-render 和 filters
<VxeColumn :filter-render="getColumnFilterRender(column)" :filters="getColumnFilters(column)">
- 2、filter-render 主要用来配置渲染器(对应筛选组件)
js
getColumnFilterRender(column) {
if (!column.field || column.filters === false) return void 0
const { props: filterRenderProps, ...restFilterRender } = column.filterRender ?? {}
// debugger
return {
name: BaseFilterRenderName, // 关键点,指定渲染器名称
...restFilterRender,
props: {
// 如果传递了 filters 则将 filters 作为 options
options: getColumnCustomValueOptions(column),
multiple: column.filterMultiple ?? true,
...filterRenderProps,
},
}
},- 3、filters 配置筛选数据(筛选条件)
js
getColumnFilters(column) {
if (!column.field || column.filters === false) return void 0
let filters
if (this.filtersMap[column.field]) {
filters = this.filtersMap[column.field]
} else {
filters = [{ data: {} }]
// 保证每次拿到的是同一个 filters 对象, 而不是每次都重新创建一个
this.filtersMap[column.field] = filters
}
const data = filters[0].data
// 参数设置
data.valueType = getColumnFilterValueType(column)
data.valueFormat = getColumnFilterValueFormat(column, data.valueType)
// 默认值设置
if (!data.condition) {
data.condition = getDefaultFilterCondition(data.valueType)
}
if (data.value === undefined) {
data.value = getDefaultFilterValue(data.valueType)
}
if (data.values === undefined) {
data.values = getDefaultFilterValues(data.valueType)
}
return filters
},到此,vxe-table 二次封装(筛选、排序)配置完毕
分页封装
- 将
<ElPagination />与<VxeTable><VxeColumn />組件进行组合 - 将
<ElPagination />组件触发事件 emit 到最外层
注意点
- VxeTable 插件注册
- 需要二次封装组件和 vxe-table组件 同时注册,才能将配置渲染出来
js
import VxeTablePlus from './plugin/vxe-table-plus'
import VxeTable from 'vxe-table'
// 安装 VXETable 插件
Vue.use(VxeTablePlus)
Vue.use(VxeTable)