背景
项目中要实现表格地区筛选的功能,一开始使用element-plus 的el-table + el-cascader做,但是没多久就放弃了。因为el-table没有表头筛选的自定义内容的插槽。也就是说,要实现这个功能得原创不少代码,得不偿失,问题的关键就是寻找有筛选插槽的表格插件
vxe-table
当然这类的插槽有很多,这里我们选用的是vxe-table 表格控件
插槽示例:
<vxe-column field="age" title="Age" :filters="ageOptions" :filter-method="filterAgeMethod">
<template #filter="{ $panel, column }">
<input type="type" v-for="(option, index) in column.filters" :key="index" v-model="option.data" @input="$panel.changeOption($event, !!option.data, option)">
</template>
</vxe-column>
如上图所示,template 里面的input就是自定义内容,这里的传参比较奇特,由于是自定义插槽,并不需要列表,需要ageOptions的一个data属性进行传参
const ageOptions = ref([
{ data: '' }
])
data 属性承载着选中的数据,根据vxe提供的示例,结合el-cascader 级联选择器对地区选择的支持,可以完成表格地区筛选的功能
结合el-cascader
把示例里面的input,换成el-cascader即可
<vxe-column
title="地区"
align="center"
field="monitorArea"
:filters="areaNameFilter"
:filter-method="filterMethod"
trigger="click"
>
<template #filter="{ $panel, column }">
<el-cascader-panel
v-for="(option, index) in column.filters"
v-model="option.data"
:props="cascaderProps"
:options="areaTree"
@change="panel.changeOption($event, !!option.data, option)"
/>
</template>
</vxe-column>
areaTree 是级联数据,示例如下:
[
{
label: '内蒙古',
value: '1',
children: [
{
label: '包头',
value: '13'
}
]
}
]
筛选
前端筛选
实现vxe-table前端筛选,配置filter-method属性,接收的是一个函数例如::filter-method="filterMethod"
那么函数就可以这样写
const filterMethod = ({ option, row }) => {
return row.areaId === option.data
}
areaId
表示表格列表中表示地区的字段,这段函数会遍历所有数据,找到所含有相应areaId的数据,当然,支持多选的话就要这样设置
const filterMethod = ({ option, row }) => {
return option.data.includes(row.areaId)
}
后端筛选
对于后端分页的表格来讲,前端展示的只是一部分数据,这样的话筛选就要传入后台参数,让后台去数据库中查找复合条件的数据进行返回,于是我们需要对vxe-table进行一些配置
首先,filter-method不需要配置了,取而代之的是,vxe-table根节点需要配置:filter-config="{ remote: true }"
,然后需要监听表格中的筛选确定操作,@filter-change="filterChange"
, 将我们在filter属性传入列表中的data取出来,添加到接口搜索的参数中,这样就得到我们想要的结果。
以vue3的代码为例
const filterChange = (value) => {
value.filterList.map((item) => {
if (item.field == 'areaId') {
queryParams.value.areaId = transformArea(item.datas).join(', ')
}
})
// 执行查询操作
getList(queryParams.value)
}
多选
el-cascader 组件支持多选,在标签中添加 :props=“props” 并设置 props = { multiple: true } 来开启多选模式。
<template>
<el-cascader :props="props" />
</template>
<script lang="ts">
export default {
setup() {
return {
props: {
// props.
multiple: true,
},
}
},
}
</script>