vxe-table動(dòng)態(tài)列篩選以及篩選項(xiàng)動(dòng)態(tài)變化的問(wèn)題及解決
vxe-table動(dòng)態(tài)列篩選以及篩選項(xiàng)動(dòng)態(tài)變化
需求場(chǎng)景
- table 的列是由接口動(dòng)態(tài)返回的;
- 列的篩選項(xiàng)就是數(shù)據(jù)的值,比如【姓名】這個(gè)字段總共有三個(gè)值,那么姓名這一列的篩選項(xiàng)就是這三個(gè)值本身;
- 當(dāng)有一列篩選后,其他列的篩選項(xiàng)也要?jiǎng)討B(tài)變化。
vxe-table 版本:4.9.14
完整代碼
vue template 部分:
<vxe-table
ref="vxeTableRef"
:data="state.tableData"
height="100%"
border
@filter-change="handleFilterChange"
>
<vxe-column
v-for="colOpt in columnsOptions"
:key="colOpt.field"
:field="colOpt.field"
:title="colOpt.title"
align="center"
resizable
sortable
:filters="colOpt.filters"
:filter-method="colOpt.filterMethod"
/>
</vxe-table>script 部分:
<script setup lang="ts">
// 其他代碼
const vxeTableRef = ref();
const handleSearch = () => {
// 獲取table數(shù)據(jù)部分的邏輯
API(params).then((res: any) => {
// ...
state.tableData = data || [];
if (state.tableData.length > 0) {
// 在數(shù)據(jù)加載后重置所有篩選
nextTick(() => {
if (vxeTableRef.value) {
vxeTableRef.value.clearFilter();
}
});
}
});
}
// 下面是處理列篩選的邏輯
// 獲取篩選選項(xiàng)
const getColumnFilters = (column: string) => {
// 使用 Map 來(lái)提高性能
const uniqueMap = new Map();
for (const row of state.tableData) {
const value = row[column];
if (!uniqueMap.has(value)) {
uniqueMap.set(value, {
label: value == null || value == "" ? "(空)" : String(value),
value: value,
checked: false
});
}
}
return Array.from(uniqueMap.values());
};
// 創(chuàng)建篩選方法
const createFilterMethod = (column: string) => {
return ({ value, row }: { value: any; row: any }) => {
const cellValue = row[column];
// 處理空值的情況
if (value === null || value === "") {
return cellValue === null || cellValue === "";
}
// 如果單元格值是數(shù)字,進(jìn)行數(shù)字比較
if (typeof cellValue === "number") {
return cellValue === Number(value);
}
// 默認(rèn)進(jìn)行字符串比較
return String(cellValue) === String(value);
};
};
// 數(shù)據(jù)是異步加載的,使用計(jì)算屬性來(lái)處理列配置
const columnsOptions = computed(() => {
return state.columns.map(col => ({
field: col,
title: col,
filters: getColumnFilters(col),
filterMethod: createFilterMethod(col)
}));
});
// 處理篩選變化
const handleFilterChange = (params: any) => {
// 獲取當(dāng)前表格中可見(jiàn)的行數(shù)據(jù)
const { filterList } = params;
// 如果沒(méi)有篩選項(xiàng),就刷新
if (!filterList || filterList.length === 0) {
handleSearch();
}
// 篩選已經(jīng)應(yīng)用,獲取處理后的可見(jiàn)數(shù)據(jù)
const visibleData = vxeTableRef.value?.getTableData().visibleData || [];
// 獲取當(dāng)前被篩選的列,避免修改它們的篩選項(xiàng)
const filteredColumns = new Set(filterList.map((item: any) => item.field));
// 更新篩選狀態(tài)
nextTick(() => {
// 只更新未被篩選的列
state.columns.forEach(column => {
// 跳過(guò)當(dāng)前正在篩選的列
if (filteredColumns.has(column)) return;
// 為此列生成新的篩選選項(xiàng),但僅從可見(jiàn)數(shù)據(jù)中獲取
const uniqueMap = new Map();
for (const row of visibleData) {
const value = row[column];
if (!uniqueMap.has(value)) {
uniqueMap.set(value, {
label: value == null || value === "" ? "(空)" : String(value),
value: value,
checked: false
});
}
}
// 更新此列的篩選項(xiàng)
if (vxeTableRef.value) {
vxeTableRef.value.setFilter(column, Array.from(uniqueMap.values()));
}
});
});
};
</script>里面關(guān)鍵的一個(gè)點(diǎn)在于,vxe-table 篩選后的展示數(shù)據(jù)跟我們的源數(shù)據(jù)是分開(kāi)的,所以篩選觸發(fā)的事件中,我們應(yīng)該拿 visibleData 來(lái)做篩選項(xiàng)的動(dòng)態(tài)處理。
由于邏輯可復(fù)用,所以記錄一下,需要用的時(shí)候直接copy就好了。
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Vue實(shí)現(xiàn)active點(diǎn)擊切換方法
下面小編就為大家分享一篇Vue實(shí)現(xiàn)active點(diǎn)擊切換方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-03-03
vue.js中window.onresize的超詳細(xì)使用方法
這篇文章主要給大家介紹了關(guān)于vue.js中window.onresize的超詳細(xì)使用方法,window.onresize 是直接給window的onresize屬性綁定事件,只能有一個(gè),文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-12-12
對(duì)Vue.js之事件的綁定(v-on: 或者 @ )詳解
今天小編就為大家分享一篇對(duì)Vue.js之事件的綁定(v-on: 或者 @ )詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-09-09
詳解刷新頁(yè)面vuex數(shù)據(jù)不消失和不跳轉(zhuǎn)頁(yè)面的解決
這篇文章主要介紹了詳解刷新頁(yè)面vuex數(shù)據(jù)不消失和不跳轉(zhuǎn)頁(yè)面的解決,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-01-01
使用Vue實(shí)現(xiàn)Markdown文檔的展示和解析
在Vue項(xiàng)目中,Markdown文檔的使用越來(lái)越普遍,因此在Vue中如何進(jìn)行Markdown文檔展示與解析也成為了一個(gè)熱門話題,本文將介紹如何使用Vue實(shí)現(xiàn)Markdown文檔的展示和解析,文中通過(guò)代碼示例講解的非常詳細(xì),需要的朋友可以參考下2024-01-01
Vue實(shí)現(xiàn)模糊查詢的簡(jiǎn)單示例
在Vue中實(shí)現(xiàn)模糊查詢,你可以使用JavaScript的filter和includes方法,結(jié)合Vue的v-for指令,本文給大家舉了一個(gè)簡(jiǎn)單的示例,并通過(guò)代碼示例給大家介紹的非常詳細(xì),需要的朋友可以參考下2024-01-01

