element-plus的el-table自定義表頭篩選查詢功能實(shí)現(xiàn)
一、效果

二、代碼
1.代碼可直接復(fù)制使用
<template>
<div class="page-view" @click="handleClickOutside">
<el-button @click="resetFilters">Reset Filters</el-button>
<el-table ref="tableRef" row-key="date" :data="filteredData" style="width: 100%">
<el-table-column prop="date" label="Date" sortable width="180" column-key="date" />
<el-table-column prop="name" label="Name" sortable width="180">
<template #header>
<div style="display: inline-block; align-items: center;">
<span>Name</span>
<el-icon ref="buttonRef" @click.stop="toggleNameFilter(buttonRef, 'nameFilter')"
style="cursor: pointer; margin-left: 10px;"
:style="{ color: searchDate.nameFilter ? '#007d7b' : '#85888e' }">
<Filter />
</el-icon>
</div>
</template>
<template #default="scope">
<span>{{ scope.row.name }}---</span>
</template>
</el-table-column>
<el-table-column prop="address" label="Address" width="300" />
<el-table-column prop="tag" label="Tag">
<template #header>
<div style="display: inline-block; align-items: center;">
<span>Tag</span>
<el-icon ref="buttonRef2" @click.stop="toggleNameFilter(buttonRef2, 'tagFilter')"
style="cursor: pointer; margin-left: 10px;"
:style="{ color: searchDate.tagFilter ? '#007d7b' : '#85888e' }">
<Filter />
</el-icon>
</div>
</template>
<template #default="scope">
<el-tag :type="scope.row.tag === 'Home' ? 'primary' : 'success'">{{ scope.row.tag }}</el-tag>
</template>
</el-table-column>
</el-table>
{{ visible }}
<pre>{{ searchDate }}</pre>
<el-popover :visible="visible" :virtual-ref="refName" placement="bottom" :width="'fit-content'">
<div>
<el-input v-if="showKey === 'nameFilter'" v-model="searchDate.nameFilter" placeholder="輸入框"
@input="applyNameFilter" clearable style="margin-top: 10px; width: 150px;" />
<el-select v-if="showKey === 'tagFilter'" v-model="searchDate.tagFilter" placeholder="Select Tag"
@change="applyTagFilter" clearable style="margin-top: 10px; width: 150px;">
<el-option label="Home" value="Home" />
<el-option label="Office" value="Office" />
</el-select>
<div class="mt" style="text-align: right;">
<el-button type="info" link @click="cancelFilter">重置</el-button>
<el-button type="primary" link @click="searchFilter">篩選</el-button>
</div>
</div>
</el-popover>
</div>
</template>
<script setup>
import { ref, computed, unref } from 'vue'
// import { ElIconSearch, ElIconSArrowDown } from '@element-plus/icons-vue'
import { Filter } from '@element-plus/icons-vue'
import { ClickOutside as vClickOutside } from 'element-plus'
const buttonRef = ref()
const buttonRef2 = ref()
const popoverRef = ref()
const onClickOutside = () => {
console.log(123);
if (unref(popoverRef) && unref(popoverRef).popperRef) {
unref(popoverRef).popperRef?.delayHide?.()
}
}
const showKey = ref(undefined) // 當(dāng)前展示哪個(gè)篩選窗
const visible = ref(false) // 手動控制篩選窗顯隱
const refName = ref(null) // 動態(tài)綁定在哪個(gè)表頭圖標(biāo)下
const tableRef = ref() // 表格ref
const searchDate = ref({
nameFilter: undefined,
tagFilter: undefined,
}) // 查詢參數(shù)
// 全局重置
const resetFilters = () => {
searchDate.value.nameFilter = undefined
searchDate.value.tagFilter = undefined
applyNameFilter()
applyTagFilter()
getData()
}
// 觸發(fā)篩選
const toggleNameFilter = (ref, key) => {
if (showKey.value !== key) {
visible.value = false
getData()
}
refName.value = ref
showKey.value = key
visible.value = !visible.value
}
// 點(diǎn)擊其他元素
const handleClickOutside = () => {
// visible.value = false;
};
// 重置
const cancelFilter = () => {
searchDate.value[showKey.value] = undefined
visible.value = false;
getData()
}
// 篩選
const searchFilter = () => {
visible.value = false;
getData()
}
// 單獨(dú)過濾
const applyNameFilter = () => {
// Filtering logic can be customized if needed
}
const applyTagFilter = () => {
// Filtering logic can be customized if needed
}
// 原數(shù)據(jù)
const tableData = [
{
date: '2016-05-03',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles',
tag: 'Home',
},
{
date: '2016-05-02',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles',
tag: 'Office',
},
{
date: '2016-05-04',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles',
tag: 'Home',
},
{
date: '2016-05-01',
name: 'Jack',
address: 'No. 189, Grove St, Los Angeles',
tag: 'Office',
},
]
// 列表顯示的數(shù)據(jù)
// const filteredData = computed(() => {
// return tableData.filter((item) => {
// const nameMatch = searchDate.value.nameFilter ? item.name.toLowerCase().includes(searchDate.value.nameFilter.toLowerCase()) : true
// const tagMatch = searchDate.value.tagFilter ? item.tag === searchDate.value.tagFilter : true
// return nameMatch && tagMatch
// })
// })
const filteredData = ref(JSON.parse(JSON.stringify(tableData)))
// 獲取數(shù)據(jù)
const getData = () => {
filteredData.value = tableData.filter((item) => {
const nameMatch = searchDate.value.nameFilter ? item.name.toLowerCase().includes(searchDate.value.nameFilter.toLowerCase()) : true
const tagMatch = searchDate.value.tagFilter ? item.tag === searchDate.value.tagFilter : true
return nameMatch && tagMatch
})
}
</script>
<style lang="scss" scoped>
:deep(.el-popover) {
width: fit-content !important;
}
:deep(.el-popover.el-popper) {
width: fit-content !important;
}
</style>三、問題
1.使用el-popover完成篩選框
同時(shí)通過:visible="visible"來控制篩選框顯隱,但是在el-popover下就不能使用<template #reference>子元素 (如使用子元素,就沒法將篩選框其定位到每個(gè)表頭;除非你給每一個(gè)表頭的el-icon圖表外都寫一個(gè)el-popover來包裹,那樣10個(gè)表頭需要寫10個(gè)el-popover)。所以控制臺會報(bào)警告提示:
ElementPlusError: [ElOnlyChild] no valid child node found at debugWarn (chunk-32EVVALS.js?v=a0ab03ed:9136:37)

暫無好的解決辦法,大家有方案可提供下。
——————————————————————————————————————————————————
更新: 我直接把el-table也給進(jìn)行了封裝,動態(tài)遍歷渲染表格(也就動態(tài)渲染了表頭,也就可以給表頭el-icon圖標(biāo)外包裹一個(gè)el-popover來實(shí)現(xiàn)各個(gè)表頭的篩選,且不會報(bào)告警報(bào)錯(cuò))
到此這篇關(guān)于element-plus的el-table自定義表頭篩選查詢的文章就介紹到這了,更多相關(guān)element-plus的el-table表頭篩選查詢內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- vue3?element?plus?table?selection展示數(shù)據(jù),默認(rèn)選中功能方式
- Vue3+Element-Plus使用Table預(yù)覽圖片發(fā)生元素遮擋的解決方法
- vue3使用element-plus再次封裝table組件的基本步驟
- vue3使用elementPlus進(jìn)行table合并處理的示例詳解
- vue3+element Plus實(shí)現(xiàn)在table中增加一條表單數(shù)據(jù)的示例代碼
- vue3+elementplus基于el-table-v2封裝公用table組件詳細(xì)代碼
- Vue3中Element Plus Table(表格)點(diǎn)擊獲取對應(yīng)id方式
- vue3 elementplus table合并寫法
- Element?UI/Plus中全局修改el-table默認(rèn)樣式的解決方案
- ElementPlus?Table表格實(shí)現(xiàn)可編輯單元格
相關(guān)文章
Vue3?接入?i18n?實(shí)現(xiàn)國際化多語言案例分析
在?Vue.js?3?中實(shí)現(xiàn)網(wǎng)頁的國際化多語言,最常用的包是?vue-i18n,通常我們會與?vue-i18n-routing?一起使用,這篇文章主要介紹了Vue3?如何接入?i18n?實(shí)現(xiàn)國際化多語言,需要的朋友可以參考下2024-07-07
Vue如何使用patch-package優(yōu)雅地修改第三方依賴庫
在前端開發(fā)中,有時(shí)我們需要對第三方依賴庫進(jìn)行修改以滿足項(xiàng)目需求,patch-package 是一個(gè)優(yōu)秀的工具,可以幫助我們優(yōu)雅地管理這些修改,下面我們來看看具體操作吧2025-03-03
vue+element_ui上傳文件,并傳遞額外參數(shù)操作
這篇文章主要介紹了vue+element_ui上傳文件,并傳遞額外參數(shù)操作,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-12-12
Vue.js與 ASP.NET Core 服務(wù)端渲染功能整合
本文通過案例給大家詳細(xì)分析了ASP.NET Core 與 Vue.js 服務(wù)端渲染,需要的朋友可以參考下2017-11-11
關(guān)于Vite項(xiàng)目打包后瀏覽器兼容性問題的解決方案
本文主要介紹了關(guān)于Vite項(xiàng)目打包后瀏覽器兼容性問題的解決方案,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-08-08
詳解Vue demo實(shí)現(xiàn)商品列表的展示
這篇文章主要介紹了Vue demo實(shí)現(xiàn)商品列表的展示,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-05-05
使用mint-ui開發(fā)項(xiàng)目的一些心得(分享)
下面小編就為大家?guī)硪黄褂胢int-ui開發(fā)項(xiàng)目的一些心得(分享)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-09-09
Vue實(shí)現(xiàn)導(dǎo)航欄點(diǎn)擊當(dāng)前標(biāo)簽變色功能
這篇文章主要為大家詳細(xì)介紹了Vue實(shí)現(xiàn)導(dǎo)航欄點(diǎn)擊當(dāng)前標(biāo)簽變色功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-05-05

