痛点: 表格显示列太多,用户只想看到自己想要看的列数据
解决思路: 让用户可自己勾选显示的列
方案: 已勾选显示的列show属性为true,表格的列是动态渲染(show为true显示)
<template>
<!-- 表格动态列筛选 -->
<el-container class="a-section" style="margin-top: 150px;">
<el-table ref="dataTable" :data="tableData" element-loading-text="加载中" fit>
<template v-for="(item, index) in tableHeader">
<el-table-column v-if="tableHeader[index].isShow" :key="index" :label="item.label" :prop="item.prop" align="center">
<template slot-scope="scope">
<span>{{ scope.row[item.prop] }}</span>
</template>
</el-table-column>
</template>
<el-table-column label="操作" fixed="right">
<template slot="header" slot-scope="scope">
<a href="javascript:;">
<el-popover :ref="`popover-${scope.$index}`" width="400" placement="left" trigger="click">
<p>表格显示列调整:</p>
<el-checkbox :indeterminate="isIndeterminate" v-model="checkAll" @change="handleCheckAllChange">全选</el-checkbox>
<p></p>
<el-checkbox-group class="columnSelectGroup" v-model="columnSelecteds" @change="columnSelectedChange">
<el-checkbox v-for="item in tableHeader" v-show="item.label" :key="item.label" :label="item.label" />
</el-checkbox-group>
<div slot="reference">
<i class="el-icon-s-grid" />
操作
</div>
</el-popover>
</a>
</template>
<template slot-scope="scope">
<el-button class="a-btn-mini">
编辑
</el-button>
</template>
</el-table-column>
</el-table>
</el-container>
</template>
<script>
export default {
name: 'move_table',
data: function () {
var vm = this;
return {
tableHeader: [
{
label: '日期',
prop: 'date',
},
{
label: '姓名',
prop: 'name',
},
{
label: '省',
prop: 'province',
},
{
label: '区',
prop: 'city',
},
{
label: '地址',
prop: 'address',
},
{
label: '邮编',
prop: 'zip',
},
{
label: '标签',
prop: 'tag',
},
],
tableData: [{
date: '2016-05-02',
name: '王小虎',
province: '上海',
city: '普陀区',
address: '上海市普陀区金沙江路 1518 弄',
zip: 200333,
tag: '家'
}, {
date: '2016-05-04',
name: '王小虎',
province: '上海',
city: '普陀区',
address: '上海市普陀区金沙江路 1517 弄',
zip: 200333,
tag: '公司'
}, {
date: '2016-05-01',
name: '王小虎',
province: '上海',
city: '普陀区',
address: '上海市普陀区金沙江路 1519 弄',
zip: 200333,
tag: '家'
}, {
date: '2016-05-03',
name: '王小虎',
province: '上海',
city: '普陀区',
address: '上海市普陀区金沙江路 1516 弄',
zip: 200333,
tag: '公司'
}],
isIndeterminate: true, //indeterminate 属性用以表示 checkbox 的不确定状态,一般用于实现全选的效果
checkAll: false, //是否全选
columnSelecteds: [], // 已选择的项
}
},
watch: {
},
mounted: function () {
this.initColumnSelected()
},
methods: {
// 初始化要显示的列
initColumnSelected() {
// 拿到所有页面中的表格列,并赋值isShow字段
let allLabels = this.tableHeader.map((item) => {
item.isShow = true;
return item.label;
})
// 先存储,因为isShow是后面加上的,页面不会渲染,要清空掉tableHeader重新渲染一遍
let tableHeader = Common.Util.deepCopy(this.tableHeader)
this.tableHeader = []
// 从缓存中取表格列
if (JSON.parse(localStorage.getItem(this.$options.name + 'columnSelecteds')) && JSON.parse(localStorage.getItem(this.$options.name + 'columnSelecteds')).length) {
// 如果有,则要判断缓存的表格列中是否有已经删掉的列,有则去除掉
let oldColumnSelecteds = JSON.parse(localStorage.getItem(this.$options.name + 'columnSelecteds'))
this.columnSelecteds = oldColumnSelecteds.filter(value => {
return allLabels.includes(value)
});
} else { //如果没有,则所有的表格列都显示
this.columnSelecteds = allLabels
}
this.tableHeader = tableHeader;
this.columnSelectedChange(this.columnSelecteds)
},
// 显示列变动事件
columnSelectedChange(newArrayVal) {
// 计算为被选中的列标题数组
var nonSelecteds = this.tableHeader
.filter((item) => newArrayVal.indexOf(item.label) === -1)
.map((item) => item.label)
// 根据计算结果进行表格重绘
this.tableHeader.filter((item) => {
const isNonSelected = nonSelecteds.indexOf(item.label) !== -1
if (isNonSelected) {
// 隐藏未选中的列
item.isShow = false
this.$nextTick(() => {
this.$refs.dataTable.doLayout()
})
} else {
// 显示已选中的列
item.isShow = true
this.$nextTick(() => {
this.$refs.dataTable.doLayout()
})
}
})
this.judgeAll(newArrayVal)
},
// 全选显示逻辑
judgeAll(newArrayVal) {
let options = this.tableHeader.map((item) => {
return item.label
})
let checkedCount = newArrayVal.length;
this.checkAll = checkedCount === options.length;
this.isIndeterminate = checkedCount > 0 && checkedCount < options.length;
localStorage.setItem(this.$options.name + 'columnSelecteds', JSON.stringify(this.columnSelecteds))
},
// 全选变动事件
handleCheckAllChange(val) {
let options = this.tableHeader.map((item) => {
return item.label
})
this.columnSelecteds = val ? options : [];
this.isIndeterminate = false;
this.columnSelectedChange(this.columnSelecteds)
},
},
}
</script>
<style lang="scss" scoped>
.columnSelectGroup {
display: flex;
// flex-direction: column;
flex-wrap: wrap;
.el-checkbox {
width: 45%;
margin-left: 0px;
margin-right: 0px;
}
}
</style>