效果展示
渲染出来的表格
数据是无序的,这里表格的筛选列表采用递增排序,若是字符则按照Unicode码位值排序
这里筛选身高是170的
筛选前
筛选后
并且其它的筛选列表也会根据当前数据联动变化,这里以地区为例
当对其它列也做筛选操作,所有的筛选列表都会跟着联动,这里对身高和地区都做筛选,年龄的筛选列表更新
页面使用
给el-table绑定
filter-change事件,该事件在操作表格筛选功能时触发,会返回当前筛选条件
<template>
<el-table
:data="tableData"
@filter-change="filterChange"
height="400"
stripe
border
>
<el-table-column
v-for="item in columns"
:label="item.label"
:prop="item.prop"
:width="item.width"
:filters="item.filters"
:filter-method="item.filterMethod"
:columnKey="item.columnKey"
>
</el-table-column>
</el-table>
</template>
<script setup lang="ts">
import { onMounted, ref } from 'vue';
import { filterColumn } from './utils.ts'
import { columns } from "./data.ts";
const tableData = ref([])
let filterChange: (newFilters: any) => void = (a) => {}
const onQuery = async () => {
// 这里模拟数据
tableData.value = [
{
code: 1003,
age: 19,
address: '天津',
height: 180
},
{
code: 1004,
age: 20,
address: '上海',
height: 170
},
{
code: 1001,
age: 18,
address: '北京',
height: 170
},
{
code: 1002,
age: 19,
address: '北京',
height: 166
},
]
// 这里使用筛选方法,返回的filterChange函数,直接赋值绑定到el-table上
const filterObj = filterColumn(columns.value, tableData.value, true)
filterChange = filterObj.filterChange
}
onMounted(() => {
onQuery()
})
</script>
表格列数据
data.ts 文件中导出的表格列数据:
filters和filterMethod为筛选功能必须的属性;- 设置
columnKey为当前列的prop字段,用来在表格filter-change事件触发后,判断当前是做的哪一列的筛选;columns的数据必须是响应式数据,否则表格的筛选列表不会有内容
import { ref } from 'vue'
export const columns = ref([
{
label: "编号",
prop: "code",
width: 100,
filters: [],
filterMethod: (value, row, column) => row.code == value,
columnKey: "code"
},
{
label: "年龄",
prop: "age",
width: 100,
filters: [],
filterMethod: (value, row, column) => row.age == value,
columnKey: "age"
},
{
label: "地区",
prop: "address",
width: 100,
filters: [],
filterMethod: (value, row, column) => row.address == value,
columnKey: "address"
},
{
label: "身高",
prop: "height",
width: 100,
filters: [],
filterMethod: (value, row, column) => row.height == value,
columnKey: "height"
},
])
表格列筛选方法
utils.ts 文件中导出的方法
/**
* 表格列筛选方法
* @param columns 表格绑定的列渲染数据
* @param tableData 表格数据
* @param isSort 是否排序,默认true,递增排序。
* @returns filterChange el-table筛选功能触发函数
* 注:实现表格列筛选功能,传递的 columns 要是响应式数据。
*/
export const filterColumn = (columns: any[], tableData: Array<any>, isSort = true ) => {
// // 为每一列添加筛选标识,但是发现筛选函数触发后,筛选标识有时候会被清空,所以将筛选标识写在columns中
// columns.forEach((v) => {
// v.columnKey = v.prop
// })
// 生成表格筛选功能所需的内容对象
const generateFilters = (tData) => {
// 1. 先清空原来columns数组中filters的内容
columns.forEach((v) => {
if (v.filters) {
v.filters.splice(0)
}
});
// 2. 遍历表格列数组,对有filters属性的这一项,添加表格筛选功能所需的内容对象
columns.forEach((a) => {
if (a.filters) {
tData.forEach((item) => {
if (!a.filters.some((i) => i.text === item[a.prop])) {
a.filters.push({ text: item[a.prop], value: item[a.prop] })
}
});
}
});
// 3. 对filters属性的数组进行排序
if (isSort) {
columns.forEach((a) => {
if (a.filters.length > 0) {
if (isNaN(+a.filters[0].value)) {
a.filters.sort((s, f) => {
if (s.value > f.value) {
return 1
} else if (s.value < f.value) {
return -1
} else {
return 0
}
})
} else {
a.filters.sort((s, f) => {
return +s.value - +f.value
})
}
}
})
}
}
generateFilters(tableData)
// 筛选功能触发后,找出符合条件的表格数据
let filterData = {}
const filterChange = (curFilters) => {
Object.assign(filterData, curFilters)
const filterTableData = tableData.flatMap(item => {
return Object.keys(filterData).every(key => filterData[key].length === 0 || filterData[key].includes(item[key])) ? item : []
})
console.log('filterTableData', filterTableData)
generateFilters(filterTableData)
}
return {
filterChange
}
}