vue使用el-table筛选tree树形结构的数据问题

 更新时间:2024年07月25日 10:02:40   作者:蜂巢糖FCT  
这篇文章主要介绍了vue使用el-table筛选tree树形结构的数据问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

实现难点

1.对于普通列数据el-table表格可做到多条件筛选,但是对于带tree树形结构类型的数据只能筛选到最上层节点,子节点不会筛选

2.考虑到缺陷,因此查看文档只能通过文档提供的filter-change事件手动筛选数据。

思路

1.通过filter-change事件使用filterObj对象保存点击的筛选状态    

2.先将当前树形数据转变成普通列数据,再进行手动过滤,过滤后以 普通列数据展示   

3.当无筛选条件时再以树形结构展示 

图例

实现步骤

1.数据初始化

data:{
    return{
         targetNode:{},//总数据,保持tree数据类型
         tableData:[],//展示在table上的数据
         filterObj:{isEnable:[],filterTypeAttr:[],filterTypeCondition:[]},//过滤条件,由于表        格组件filterchange方法只会提示当前的筛选项,
            //所以使用filterObj来保存所有筛选过的选项   
    }
}

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="筛选项" 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: '机构名称', value: '2'},{ text: '无', 
  value: ''}]"
  label="筛选类型属性">
    <template slot-scope="scope">{{ scope.row.filterTypeAttr==1?'自定义':      
      scope.row.filterTypeAttr==2?'机构名称':''}}</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)?'-机构名称':'')+ 
       (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="标识">
    <template slot-scope="scope">{{ scope.row.filterTypeCondition==1?'1-筛选类型':'2-筛选条件'}}</template>
     <template slot="header" slot-scope="scope">
       {{filterObj.filterTypeCondition.length==0?'标识':filterObj.filterTypeCondition.length==1 && filterObj.filterTypeCondition[0]==1?'标识-1-筛选类型':filterObj.filterTypeCondition.length==1 && filterObj.filterTypeCondition[0]==2?'标识-2-筛选条件':'标识-全部'}}
    </template>
</el-table-column>
<el-table-column prop="defaultSelected" label="是否属于默认展示项">
 <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)">规则式</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="状态" 
    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?'状态'
        :filterObj.isEnable.length==1 && filterObj.isEnable[0]==1?'状态-启用'
        :filterObj.isEnable.length==1 && filterObj.isEnable[0]==0?'状态-禁用':'状态-全部'}}
   </template>
</el-table-column>
</el-table>

要点:

  • default-expand-all:默认展开全部子节点
  • filterChange:获取点击的筛选条件状态,对应列表头上设置:filters属性的列

<template slot="header" slot-scope="scope">设置筛选后用来替换表头的label内容

3.filterChange函数

filterChange(filters){//触发过滤事件时过滤数据
        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=>{//层级数据转变成普通列数据
                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('线性数据',dataList);
            if(this.filterObj['isEnable'].length>0){//状态
                dataList = dataList.filter(item=>{
                    return this.filterObj['isEnable'].includes(item.isEnable)
                }) 
            }
            if(this.filterObj['filterTypeCondition'].length>0){//标识
                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('过滤数据',dataList);
            this.tableData = dataList;
        }
        
      },
      getLineData(data){//层级数据变成行数据
        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参数为当前点击的筛选项,数据结构如下:

  • 2.使用filterObj保存当前筛选状态,筛选重置时为[]空数组
  • 3.保存后判断filterObj各项是否都是空数组,是则直接赋值
  • 4.否则将树形结构转换成普通列数据,注意考虑浅克隆的问题,getLineData函数作用是将子节点children也插入到普通列中
  • 5.数据转换成普通列数据后进行过滤

实现效果

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。 

相关文章

  • vue项目之数量占比进度条实现方式

    vue项目之数量占比进度条实现方式

    这篇文章主要介绍了vue项目之数量占比进度条实现方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-12-12
  • 详解Vue+elementUI build打包部署后字体图标丢失问题

    详解Vue+elementUI build打包部署后字体图标丢失问题

    这篇文章主要介绍了详解Vue+elementUI build打包部署后字体图标丢失问题,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-07-07
  • 在Vue3中实现子组件向父组件传递数据的代码示例

    在Vue3中实现子组件向父组件传递数据的代码示例

    Vue3作为目前最热门的前端框架之一,以其轻量化、易用性及性能优势吸引了大量开发者,在开发过程中,不可避免地需要在组件之间传递数据,本文将详细讲解在Vue3中如何实现子组件向父组件传递数据,并通过具体示例代码使概念更加清晰
    2024-07-07
  • 通过vue刷新左侧菜单栏操作

    通过vue刷新左侧菜单栏操作

    这篇文章主要介绍了通过vue刷新左侧菜单栏操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-08-08
  • vue的el-select绑定的值无法选中el-option问题及解决

    vue的el-select绑定的值无法选中el-option问题及解决

    这篇文章主要介绍了vue的el-select绑定的值无法选中el-option问题及解决,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-09-09
  • vue2.0使用Sortable.js实现的拖拽功能示例

    vue2.0使用Sortable.js实现的拖拽功能示例

    本篇文章主要介绍了vue2.0使用Sortable.js实现的拖拽功能示例,具有一定的参考价值,感兴趣的小伙伴们可以参考一下。
    2017-02-02
  • vue中pinia数据一直重复获取之前的值的解决方法

    vue中pinia数据一直重复获取之前的值的解决方法

    这篇文章主要介绍了vue中pinia数据一直重复获取之前的值的解决方法,如果想让pinia数据不会重复获取之前的值需要手动强制触发 Pinia store 的状态更新,文中有详细的解决方法,需要的朋友可以参考下
    2024-04-04
  • Vue3+TypeScript埋点方面的应用实践

    Vue3+TypeScript埋点方面的应用实践

    本文详细阐述了如何在Vue3中使用TypeScript实现埋点功能,包括全局注册$track插件、Mixin实现全局埋点等,随着Vue3的逐渐普及,在实际工作中采用Vue3+TypeScript实现埋点将会变得越来越流行
    2023-08-08
  • Vue cli+mui 区域滚动的实例代码

    Vue cli+mui 区域滚动的实例代码

    下面小编就为大家分享一篇Vue cli+mui 区域滚动的实例代码,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-01-01
  • vue导出报表至excel表格三种方式

    vue导出报表至excel表格三种方式

    这篇文章主要给大家介绍了关于vue导出报表至excel表格的三种方式,导出报表是实际开发的常见功能,前后端都可以实现表格导出,本文介绍的是用vue实现,需要的朋友可以参考下
    2023-09-09

最新评论