el-table 表格列实现动态隐藏显示

通常一个表格横向展示的时候,字段过多,但是我们又想要只显示部份字段,这时可以使用本组件实现你想要的效果。

1、实现原理:通过给列添加v-if来实现动态显示与隐藏效果

一、编写列显示与隐藏控制组件


<template>
    <div>
        <el-dialog title="自定义列" class="column-dialog" :visible.sync="dialogVisible">
             <div class="columns">
                 <div class="fl">
                     <div class="ht"><b>字段列表</b><el-checkbox v-model="allcheck" @change="changeAll" class="ck">全选</el-checkbox></div>
                     <el-checkbox-group v-model="columnsGroup">
                            <el-checkbox v-for="(item, index) in columns" @change="danSelect(item,index)" :label="item" :key="index" name="type"></el-checkbox>
                     </el-checkbox-group>
                 </div>
                 <div class="fr">
                     <div class="ht"><b>已选择字段</b></div>
                     <ul>
                         <li v-for="(item, index) in selectColumns" v-if="item.show" :key="index">{{item.label}}</li>
                     </ul>
                 </div>
             </div>
             <span slot="footer" class="dialog-footer">
                    <el-button @click="dialogVisible = false">取 消</el-button>
                    <el-button type="primary" @click="select">确 定</el-button>
             </span>
        </el-dialog>
    </div>
</template>

<script>
export default{
    name:'CustomColumn',
    props:{
        columns:{
            type:Array,
            default:[]
        },
    },
    
    data(){
        return{
            allcheck:false,
            dialogVisible:false,
            selectColumns:[],
            columnsGroup:[]
        }
    },
    
    watch:{
        selectColumns:function(val){
            this.allcheck = val.length === this.columns.length
        },
    },
        
    methods:{
        //全选/反选
        changeAll(){
            if(this.allcheck){
                this.selectColumns.forEach(res=>{ 
                    res.show = true
                    this.columnsGroup.push(res.label)
                })  
                this.allcheck = true
            }else{
                this.selectColumns.forEach(res=>{ res.show = false })
                this.columnsGroup = []
                this.allcheck = false
            }
        },
        
        //单选事件
        danSelect(item,index){
            let flag = this.columnsGroup.indexOf(item)
            this.selectColumns.forEach(res=>{
                 if(res.label==item){ 
                     res.show = flag==-1?false:true
                 }
            })
        },
        
        //确认选择      
        select(){
            let flag = true
            this.selectColumns.forEach(res=>{ 
                if(res.show){ flag = false }
            })
            if(flag){
                this.$message.error("请选择列");
                return
            }
            this.$emit("selectColumns",JSON.stringify(this.selectColumns))
            this.dialogVisible = false
        }
        
    }
}
</script>
<style scoped="scoped">
/deep/ .el-dialog__header{ padding:12px; border-bottom:1px solid #eee;} 
/deep/ .el-dialog__title{ font-size:16px;}
/deep/ .el-dialog__body{padding:20px;}
.column-dialog /deep/ .el-dialog{ width:40%; min-width:550px;}
.columns{ display: flex;}   
.columns .ht{ margin-bottom:10px;}
.columns .ht .ck{ margin-left:12px;}
.columns .fl{ flex:1;}
.columns .fl .el-checkbox-group{ overflow: hidden;}
.columns .fl .el-checkbox-group .el-checkbox{ margin-right:0; float:left; width:50%; margin-top:10px;}
.columns .fr{ width:200px; border-left:1px solid #f1f1f1; padding-left:20px; margin-left:20px;}
.columns .fr ul{ max-height:375px; overflow-y:auto;}
.columns .fr ul li{ margin-bottom:5px;}
</style>

33.png

二、调用组件

<template>
    <div>
        <el-button type="success" icon="el-icon-s-tools" @click="setColumn">自定义列</el-button>
        <div class="container">
            <el-table :data="tableData" border class="table" :height="400" ref="multipleTable">
                <el-table-column type="selection" width="55" align="center"></el-table-column>
                <el-table-column prop="uid" label="用户ID" v-if="showColumns.some(r=>{ return r.label=='用户ID' && r.show })" align="center"></el-table-column>
                <el-table-column label="用户头像" v-if="showColumns.some(r=>{ return r.label=='用户头像' && r.show })" align="center"></el-table-column>
                <el-table-column label="用户账号" v-if="showColumns.some(r=>{ return r.label=='用户账号' && r.show })" align="center"></el-table-column>
                <el-table-column label="姓名" v-if="showColumns.some(r=>{ return r.label=='姓名' && r.show })" align="center"></el-table-column>
                ....
            </el-table>
        </div>
        <CustomColumn ref="columns" :columns="columns" @selectColumns="selectColumns"></CustomColumn>       
    </div>
</template>

<script>
    import CustomColumn from '../common/CustomColumn.vue';
    export default {
        components:{ CustomColumn },
        data() {
            return {        
                tableData: [],              
                columns:['用户ID','用户头像','用户账号','姓名','年龄','身高/体重','身材','职业','个人简介','所属省份','所属城市','用户来源','注册类型','手机名称','手机型号','所属品牌'], //所有列
                showColumns:[], //显示列
            };
        },  
        
        mounted() {
            this.initColumn()
        },
        
        methods: {
            
            //初始化列
            initColumn(){
                let arr = []
                this.columns.forEach(res=>{ 
                    this.showColumns.push({show:true,label:res});
                    arr.push(res)
                })
                this.$refs.columns.selectColumns = JSON.parse(JSON.stringify(this.showColumns))
                this.$refs.columns.columnsGroup = arr
                this.$refs.columns.allcheck = true
            },
            //自定义列
            setColumn(){
                this.$refs.columns.dialogVisible = true             
            },
            //获取选中列
            selectColumns(data){
                this.showColumns = JSON.parse(data)
                this.$nextTick(res=>{
                     this.$refs['multipleTable'].doLayout()
                })
            },
        }
    };
</script>

<style scoped>
    .container {
        overflow: hidden;
    }

    .table {
        width: 100%;
        font-size: 14px;
    }
</style>

方法有点笨,但是能实现,而且表格不会错位。
主要是在确定选择列后加一个

this.$nextTick(res=>{
  this.$refs['multipleTable'].doLayout()
})

网上说给列加随机数 key ,试过还是会错位。

 

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐