vue使用el-table篩選tree樹形結(jié)構(gòu)的數(shù)據(jù)問題
實(shí)現(xiàn)難點(diǎn)
1.對于普通列數(shù)據(jù)el-table表格可做到多條件篩選,但是對于帶tree樹形結(jié)構(gòu)類型的數(shù)據(jù)只能篩選到最上層節(jié)點(diǎn),子節(jié)點(diǎn)不會篩選
2.考慮到缺陷,因此查看文檔只能通過文檔提供的filter-change事件手動篩選數(shù)據(jù)。
思路
1.通過filter-change事件使用filterObj對象保存點(diǎn)擊的篩選狀態(tài)
2.先將當(dāng)前樹形數(shù)據(jù)轉(zhuǎn)變成普通列數(shù)據(jù),再進(jìn)行手動過濾,過濾后以 普通列數(shù)據(jù)展示
3.當(dāng)無篩選條件時(shí)再以樹形結(jié)構(gòu)展示
圖例

實(shí)現(xiàn)步驟
1.數(shù)據(jù)初始化
data:{
return{
targetNode:{},//總數(shù)據(jù),保持tree數(shù)據(jù)類型
tableData:[],//展示在table上的數(shù)據(jù)
filterObj:{isEnable:[],filterTypeAttr:[],filterTypeCondition:[]},//過濾條件,由于表 格組件filterchange方法只會提示當(dāng)前的篩選項(xiàng),
//所以使用filterObj來保存所有篩選過的選項(xiàng)
}
}2.表格
<el-table
:data="tableData"
row-key="id"
border
default-expand-all
v-loading="loading"
@filter-change="filterChange"
ref="filterTable"
:tree-props="{children: 'children', hasChildren: 'hasChildren'}">
<el-table-column prop="index" label="順序" width="180">
<template slot-scope="scope">{{(scope.$index + 1)}}</template>
</el-table-column>
<el-table-column prop="filterName" label="篩選項(xiàng)" width="180">
<template slot-scope="scope"><span :class="
[scope.row.filterTypeCondition==1?'filter-name':'']">{{ scope.row.filterName }}
</span><i v-if="scope.row.filterTypeAttr!==2" class="el-icon-plus" style="color:
#03a9f4;font-size: 12px;margin-left: 10px;cursor: pointer;"
@click="addCondition(scope.row)"></i>
</template>
</el-table-column>
<el-table-column
prop="filterTypeAttr"
column-key="filterTypeAttr"
:filters="[{ text: '自定義', value: '1' }, { text: '機(jī)構(gòu)名稱', value: '2'},{ text: '無',
value: ''}]"
label="篩選類型屬性">
<template slot-scope="scope">{{ scope.row.filterTypeAttr==1?'自定義':
scope.row.filterTypeAttr==2?'機(jī)構(gòu)名稱':''}}</template>
<template slot="header" slot-scope="scope">
<!-- {{filterObj.filterTypeAttr.length==0?'篩選類型屬
性':filterObj.filterTypeCondition.length==1 &&
filterObj.filterTypeCondition[0]==1?'1-篩選類型'
:filterObj.filterTypeCondition.length==1 &&
filterObj.filterTypeCondition[0]==2?'2-篩選條件':'篩選類型屬性-全部'}} -->
{{filterObj.filterTypeAttr.length==3?'篩選類型屬性-全部':'篩選類型
屬性'+(filterObj.filterTypeAttr.includes(1)?'-自定義':'')+
(filterObj.filterTypeAttr.includes(2)?'-機(jī)構(gòu)名稱':'')+
(filterObj.filterTypeAttr.includes(0)?'-無':'')}}
</template>
</el-table-column>
<el-table-column
prop="filterTypeCondition"
column-key="filterTypeCondition"
:filters="[{ text: '1-篩選類型', value: '1' }, { text: '2-篩選條件', value: '2'}]"
label="標(biāo)識">
<template slot-scope="scope">{{ scope.row.filterTypeCondition==1?'1-篩選類型':'2-篩選條件'}}</template>
<template slot="header" slot-scope="scope">
{{filterObj.filterTypeCondition.length==0?'標(biāo)識':filterObj.filterTypeCondition.length==1 && filterObj.filterTypeCondition[0]==1?'標(biāo)識-1-篩選類型':filterObj.filterTypeCondition.length==1 && filterObj.filterTypeCondition[0]==2?'標(biāo)識-2-篩選條件':'標(biāo)識-全部'}}
</template>
</el-table-column>
<el-table-column prop="defaultSelected" label="是否屬于默認(rèn)展示項(xiàng)">
<template slot-scope="scope">
{{scope.row.defaultSelected==1?'是':scope.row.defaultSelected==0?'否':''}}
</template>
</el-table-column>
<el-table-column prop="action" label="操作" width="250">
<template slot-scope="scope">
<span v-if="scope.row.filterTypeCondition==2" class="scope-span" :class="
[scope.row.rule && scope.row.rule!=''?'filter-span':'']"
@click="showRegular(scope.row)">規(guī)則式</span>
<span class="scope-span" @click="updateFilter(scope.row)">編輯</span>
<el-popconfirm
title="是否確定刪除?"
@confirm="delFilter(scope.row)"
>
<span class="scope-span" slot="reference" >刪除</span>
</el-popconfirm>
</template>
</el-table-column>
<el-table-column
prop="isEnable"
label="狀態(tài)"
column-key="isEnable"
:filters="[{ text: '啟用', value: '1' }, { text: '禁用', value: '0' }]"
>
<template slot-scope="scope">{{ scope.row.isEnable==1?'啟用':'禁用'}}</template>
<template slot="header" slot-scope="scope">
{{filterObj.isEnable.length==0?'狀態(tài)'
:filterObj.isEnable.length==1 && filterObj.isEnable[0]==1?'狀態(tài)-啟用'
:filterObj.isEnable.length==1 && filterObj.isEnable[0]==0?'狀態(tài)-禁用':'狀態(tài)-全部'}}
</template>
</el-table-column>
</el-table>要點(diǎn):
default-expand-all:默認(rèn)展開全部子節(jié)點(diǎn)filterChange:獲取點(diǎn)擊的篩選條件狀態(tài),對應(yīng)列表頭上設(shè)置:filters屬性的列
<template slot="header" slot-scope="scope">設(shè)置篩選后用來替換表頭的label內(nèi)容
3.filterChange函數(shù)
filterChange(filters){//觸發(fā)過濾事件時(shí)過濾數(shù)據(jù)
console.log('filters',filters);
if(filters['isEnable']){
this.filterObj['isEnable'] = filters['isEnable'].map(Number);
}
if(filters['filterTypeAttr']){
this.filterObj['filterTypeAttr'] = filters['filterTypeAttr'].map(Number);
}
if(filters['filterTypeCondition']){
this.filterObj['filterTypeCondition'] = filters['filterTypeCondition'].map(Number);
}
if(this.filterObj['isEnable'].length==0 && this.filterObj['filterTypeAttr'].length==0 && this.filterObj['filterTypeCondition'].length==0){
this.tableData = this.targetNode.filterList;
}else{
let dataList = [];
this.targetNode.filterList.forEach(item=>{//層級數(shù)據(jù)轉(zhuǎn)變成普通列數(shù)據(jù)
let obj = {
filterName:item.filterName,
filterTypeAttr:item.filterTypeAttr,
sort:item.sort,
isEnable:item.isEnable,
columnId:item.columnId,
id:item.id,
filterTypeCondition:1,
index:item.index
}
dataList.push(obj);
if(item.children){
dataList = dataList.concat(this.getLineData(item.children))
}
})
console.log('線性數(shù)據(jù)',dataList);
if(this.filterObj['isEnable'].length>0){//狀態(tài)
dataList = dataList.filter(item=>{
return this.filterObj['isEnable'].includes(item.isEnable)
})
}
if(this.filterObj['filterTypeCondition'].length>0){//標(biāo)識
dataList = dataList.filter(item=>{
return this.filterObj['filterTypeCondition'].includes(item.filterTypeCondition)
})
}
if(this.filterObj['filterTypeAttr'].length>0){//屬性
console.log('11',this.filterObj['filterTypeAttr']);
dataList = dataList.filter(item=>{
return this.filterObj['filterTypeAttr'].includes(item.filterTypeAttr?item.filterTypeAttr:0)
})
}
console.log('過濾數(shù)據(jù)',dataList);
this.tableData = dataList;
}
},
getLineData(data){//層級數(shù)據(jù)變成行數(shù)據(jù)
let list = [];
data.forEach(item=>{
let obj = {};
if(item.filterTypeCondition==1){//篩選類型
obj = {
filterName:item.filterName,
filterTypeAttr:item.filterTypeAttr,
sort:item.sort,
isEnable:item.isEnable,
parentId:item.parentId,
id:item.id,
filterTypeCondition:1,
index:item.index
}
}else{
obj = {
filterName:item.filterName,
sort:item.sort,
isEnable:item.isEnable,
parentId:item.parentId,
id:item.id,
defaultSelected:item.defaultSelected,
filterTypeCondition:2,
index:item.index
}
}
list.push(obj);
if(item.children){
list = list.concat(this.getLineData(item.children))
}
})
return list;
},步驟
- 1.fiters參數(shù)為當(dāng)前點(diǎn)擊的篩選項(xiàng),數(shù)據(jù)結(jié)構(gòu)如下:

- 2.使用filterObj保存當(dāng)前篩選狀態(tài),篩選重置時(shí)為[]空數(shù)組
- 3.保存后判斷filterObj各項(xiàng)是否都是空數(shù)組,是則直接賦值
- 4.否則將樹形結(jié)構(gòu)轉(zhuǎn)換成普通列數(shù)據(jù),注意考慮淺克隆的問題,getLineData函數(shù)作用是將子節(jié)點(diǎn)children也插入到普通列中
- 5.數(shù)據(jù)轉(zhuǎn)換成普通列數(shù)據(jù)后進(jìn)行過濾
實(shí)現(xiàn)效果

總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
vue使用import.meta.glob動態(tài)導(dǎo)入多個(gè)模塊方式
文章介紹了Vite提供的`import.meta.glob`功能,用于動態(tài)導(dǎo)入多個(gè)模塊,它通過glob模式匹配文件,返回一個(gè)對象,鍵為文件路徑,值為返回Promise的動態(tài)導(dǎo)入函數(shù),支持eager模式直接導(dǎo)入和as選項(xiàng)指定導(dǎo)入方式,如原始字符串或文件URL,適用于Vite或Rollup項(xiàng)目2025-10-10
Vue實(shí)現(xiàn)開關(guān)按鈕拖拽效果
這篇文章主要為大家詳細(xì)介紹了Vue實(shí)現(xiàn)開關(guān)按鈕拖拽效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-09-09
uniapp-ios開發(fā)之App端與webview端相互通信的方法以及注意事項(xiàng)
在uni-app與Webview之間進(jìn)行數(shù)據(jù)交互是非常常見的需求,下面這篇文章主要給大家介紹了關(guān)于uniapp-ios開發(fā)之App端與webview端相互通信的方法以及注意事項(xiàng)的相關(guān)資料,需要的朋友可以參考下2024-07-07
el-table多選toggleRowSelection不生效解決方案
這篇文章主要給大家介紹了關(guān)于el-table多選toggleRowSelection不生效的解決方案,文中通過圖文以及代碼將解決辦法介紹的非常詳細(xì),需要的朋友可以參考下2023-08-08
Vue使用new Image()實(shí)現(xiàn)圖片預(yù)加載功能
這篇文章主要介紹了如何在 Vue 中實(shí)現(xiàn)圖片預(yù)加載的一個(gè)簡單小demo以及優(yōu)化方案,文中通過代碼示例介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下2024-11-11

