非常好的问题 👍vxe-table
的列头筛选(Header Filter)是它的一个强大功能,
但你提到的「在每一列下方增加一个筛选单元格,可以直接筛选并渲染数据」——实际上属于 “表头下方的筛选行(Filter Row)”,可通过 filter-render
+ 自定义模板 / 插槽 来实现。
下面我会手把手教你实现一个完整示例 👇
✅ 一、实现目标
🔹 在 vxe-table
的每一列下方,显示一个输入框 / 下拉框作为筛选控件;
🔹 用户输入后可即时过滤表格数据;
🔹 支持多列组合筛选。
最终效果(示意):
姓名 | 年龄 | 城市 |
---|---|---|
张三 | 25 | 上海 |
李四 | 32 | 北京 |
✅ 二、基础依赖
npm install xe-utils vxe-table
在 main.js 中引入:
import 'vxe-table/lib/style.css'
import VXETable from 'vxe-table'
import { createApp } from 'vue'
import App from './App.vue'
const app = createApp(App)
app.use(VXETable)
app.mount('#app')
✅ 三、核心示例代码
<template>
<div>
<vxe-table
border
show-overflow
height="400"
:data="filteredData"
>
<!-- 姓名列 -->
<vxe-column field="name" title="姓名">
<!-- 筛选行插槽 -->
<template #filter="{ column }">
<input
v-model="filters.name"
@input="applyFilter"
placeholder="筛选姓名"
class="vxe-input"
/>
</template>
</vxe-column>
<!-- 年龄列 -->
<vxe-column field="age" title="年龄">
<template #filter="{ column }">
<input
v-model="filters.age"
@input="applyFilter"
placeholder="筛选年龄"
type="number"
class="vxe-input"
/>
</template>
</vxe-column>
<!-- 城市列 -->
<vxe-column field="city" title="城市">
<template #filter="{ column }">
<select v-model="filters.city" @change="applyFilter" class="vxe-input">
<option value="">全部</option>
<option v-for="c in cities" :key="c" :value="c">{{ c }}</option>
</select>
</template>
</vxe-column>
</vxe-table>
</div>
</template>
<script setup>
import { ref, computed } from 'vue'
const tableData = ref([
{ name: '张三', age: 25, city: '上海' },
{ name: '李四', age: 32, city: '北京' },
{ name: '王五', age: 28, city: '广州' },
{ name: '赵六', age: 30, city: '上海' }
])
// 筛选条件
const filters = ref({
name: '',
age: '',
city: ''
})
const cities = ['上海', '北京', '广州']
// 计算筛选后的数据
const filteredData = computed(() => {
return tableData.value.filter(row => {
return (
(!filters.value.name || row.name.includes(filters.value.name)) &&
(!filters.value.age || String(row.age).includes(filters.value.age)) &&
(!filters.value.city || row.city === filters.value.city)
)
})
})
function applyFilter() {
// 触发重新计算 filteredData
}
</script>
<style scoped>
.vxe-input {
width: 100%;
box-sizing: border-box;
padding: 4px 6px;
}
</style>
✅ 四、原理说明
- 使用
#filter
插槽为每一列定义一个「筛选单元格」; - 通过
filters
对象存储每一列的筛选值; - 使用
computed
计算属性filteredData
实时过滤; vxe-table
的:data
属性绑定为filteredData
;- 用户输入时触发
applyFilter()
,自动刷新数据。
✅ 五、进阶优化(可选)
1️⃣ 支持防抖搜索
import { debounce } from 'xe-utils'
const applyFilter = debounce(() => {}, 300)
2️⃣ 使用 vxe-input
/ vxe-select
组件统一风格
<vxe-input v-model="filters.name" @input="applyFilter" placeholder="筛选姓名" />
<vxe-select v-model="filters.city" @change="applyFilter">
<vxe-option value="" label="全部"></vxe-option>
<vxe-option v-for="c in cities" :key="c" :value="c" :label="c" />
</vxe-select>
3️⃣ 表头与筛选行分离显示
你也可以在表格上方用一行输入框实现全局过滤,与 vxe-table
数据联动。
✅ 总结
功能 | 实现方式 |
---|---|
每列下方显示筛选控件 | 使用 #filter 插槽 |
多列组合筛选 | computed + filters |
即时渲染 | 绑定 :data="filteredData" |
可拓展组件 | 使用 vxe-input 、vxe-select |
发表回复