非常好的问题 👍
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-inputvxe-select