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

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 ,试过还是会错位。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,033评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,725评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,473评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,846评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,848评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,691评论 1 282
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,053评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,700评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,856评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,676评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,787评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,430评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,034评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,990评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,218评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,174评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,526评论 2 343

推荐阅读更多精彩内容