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>
二、调用组件
<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 ,试过还是会错位。