目录
实现思路
基于vue+elementUI-el-table+less实现表格列的隐藏与显示-之前版本是所有的列都可以进行隐藏或者显示,依据的判断条件是数组下标。此次更新版本是部分可以隐藏与显示,判断依据是此列的prop属性。
将表格展示+分页+显示/隐藏列 组件化,其中利用slot动态展示不同的表格数据,父组件引用此组件传递相应切必须的参数,当分页或显示/隐藏列动态变化时将数据再返回父组件,父组件中的列根据回传的数据利用v-if实现列的显示与隐藏
在想要隐藏的列上加上class-name="column_visible" 并结合v-if=columnHideList[prop] 实现
主要代码
1.子组件代码(trendsTable.vue)
代码如下(示例):
<!-- create by crystalSong 分页+table+动态设置表格列的隐藏与显示 -->
<template>
<div class="trends_container">
<div class="table_container">
<el-table
ref="trendsTable"
:data="tableList"
fit
stripe
style="width: 100%"
border
:highlight-current-row="obj.hcrow"
@selection-change="handleSelectionChange"
@select="handleSelect"
@select-all="handleSelectAll"
@cell-mouse-enter="handleCellMouseEnter"
@cell-mouse-leave="handleCellMouseLeave"
>
<slot />
</el-table>
</div>
<div class="pagination_trends_wrap">
<div class="trends_oprt_wrap">
<el-popover placement="top-start" width="280" trigger="click">
<div class="trends_btn_wrap">
<el-checkbox-group v-model="visibleList" size="small">
<el-checkbox
v-for="(col, index) in columnList"
:key="index"
:label="col.label"
border
@change="visibleListChange(col,index,$event)"
>{{ col.value }}</el-checkbox>
</el-checkbox-group>
</div>
<el-button slot="reference" size="small">隐藏/显示列</el-button>
</el-popover>
</div>
<div v-if="total > 0" class="pagination_wrap">
<template>
<el-pagination
style="text-align: right;"
:current-page.sync="currentPage"
:page-sizes="[10,25,50,100]"
:page-size.sync="currentSize"
layout="total, sizes, prev, pager, next, jumper"
:total="total"
background
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
/>
</template>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'TrendsTable',
components: {},
props: {
tableList: {
type: Array,
require: true,
default: _ => []
},
hideColumnIndexs: {
type: Array,
default: _ => []
},
pageSize: {
type: Number,
default: 10
},
pageNumber: {
type: Number,
default: 1
},
total: {
required: true,
type: Number,
default: 0
},
obj: {
type: Object,
default: () => {
return {
hcrow: false
}
}
}
},
data() {
return {
visibleList: [], // 显示/隐藏列的选中下标数据集合
columnList: [], // 表格所有列名称数据列表
curHideList: {} // 动态更改的
}
},
computed: {
currentPage: {
get() {
return this.pageNumber
},
set(val) {
this.$emit('update:pageNumber', val)
}
},
currentSize: {
get() {
return this.pageSize
},
set(val) {
this.$emit('update:pageSize', val)
}
}
},
watch: {},
created() {
},
mounted() {
const _this = this
this.curHideList = {}
this.$refs.trendsTable.$children.forEach((obj, index) => {
if (obj.type) {
// 根据类名定义动态列
if (obj.className && obj.className.indexOf('column_visible') !== -1) {obj.className.indexOf('column_visible'))
_this.columnList.push(
{
'label': index,
'value': obj.type === 'selection' ? '选择' : obj.label,
'columnId': obj.columnId,
'prop': obj.prop
}
)
this.curHideList[obj.prop] = true
// _this.visibleList.push(index)
}
}
})
_this.$emit('getHideColist', this.curHideList)
},
methods: {
// handleSizeChange
handleSizeChange(val) {
// console.log(`每页 ${val} 条`);
this.$emit('pagination', { pageNumber: 1, pageSize: val })
},
// handleCurrentChange
handleCurrentChange(val) {
// console.log(`当前页码 ${val} `);
this.$emit('pagination', { pageNumber: val, pageSize: this.currentSize })
},
visibleListChange(col, index, e) {
if (e) {
// 选中
// this.curHideList[col.prop] = false
this.$set(this.curHideList, col.prop, false)
} else {
// this.curHideList[col.prop] = true
this.$set(this.curHideList, col.prop, true)
}
this.$emit('getHideColist', this.curHideList)
},
// 当选择项发生变化时会触发该事件
handleSelectionChange(selection) {
this.$emit('selection-change', selection)
},
// 当用户手动勾选数据行的 Checkbox 时触发的事件
handleSelect(selection) {
this.$emit('select', selection)
},
// 当用户手动勾选全选 Checkbox 时触发的事件
handleSelectAll(selection) {
this.$emit('select-all', selection)
},
// /当单元格 hover 进入时会触发该事件
handleCellMouseEnter(row, column, cell, event) {
this.$emit('cell-mouse-enter', row, column, cell, event)
},
// 当单元格 hover 退出时会触发该事件
handleCellMouseLeave(row, column, cell, event) {
this.$emit('cell-mouse-leave', row, column, cell, event)
},
// cell-click 当某个单元格被点击时会触发该事件 row, column, cell, event
handleCellClick(row, column, cell, event) {
this.$emit('cell-click', row, column, cell, event)
},
// cell-dblclick 当某个单元格被双击击时会触发该事件 row, column, cell, event
handleCellDbClick(row, column, cell, event) {
this.$emit('cell-dblclick', row, column, cell, event)
},
// 某一行被点击
handleRowClick(row, column, event) {
this.$emit('row-click', row, column, event)
},
// row-dblclick 当某一行被双击时会触发该事件 row, column, event
handleRowDbClick(row, column, event) {
this.$emit('row-dblclick', row, column, event)
},
// row-contextmenu 当某一行被鼠标右键点击时会触发该事件 row, column, event
handleRowContextmenu(row, column, event) {
this.$emit('row-contextmenu', row, column, event)
},
// header-click 当某一列的表头被点击时会触发该事件 column, event
handleHeaderClick(column, event) {
this.$emit('header-click', column, event)
},
// header-contextmenu 当某一列的表头被鼠标右键点击时触发该事件 column, event
handleHeaderContextmenu(column, event) {
this.$emit('header-contextmenu', column, event)
},
// sort-change 当表格的排序条件发生变化的时候会触发该事件 { column, prop, order }
handleSortChange(column, prop, order) {
this.$emit('sort-change', column, prop, order)
},
// current-change 当表格的当前行发生变化的时候会触发该事件,
// 如果要高亮当前行,请打开表格的 highlight-current-row 属性 currentRow, oldCurrentRow
handleTableCurrentChange(currentRow, oldCurrentRow) {
this.$emit('current-change', currentRow, oldCurrentRow)
}
}
}
</script>
<style lang='scss' scoped>
.trends_container{
.pagination_trends_wrap{
margin: 20px 0;
position: relative;
}
.trends_oprt_wrap{
display: inline-block;
vertical-align: top;
width: 100px;
}
.pagination_wrap{
display: inline-block;
vertical-align: top;
width: calc(100% - 105px);
margin: 0 !important;
}
}
</style>
<style lang="scss">
.trends_btn_wrap{
.el-checkbox-group{
label{
margin: 0 !important;
margin: 0 10px !important;
margin-bottom: 15px !important;
}
}
}
.table_container .el-table .cell{
text-overflow: initial !important;
}
</style>
2.父组件-引用此组件主要代码
代码如下(示例):
<trends-table
ref="trendtable"
v-loading="tableLoading"
:table-list="dataList"
:page-size.sync="authorizeForm.pageSize"
:page-number.sync="authorizeForm.pageNumber"
:total="totalRows"
@getHideColist="getHideColist"
@pagination="paginationHadle"
>
<el-table-column key="name" v-if="!columnHideList['name']" class-name="column_visible" label="姓名" prop="name" align="center" />
<el-table-column key="age" v-if="!columnHideList['age']" label="年龄" prop="age" align="center" class-name="column_visible"/>
<el-table-column key="phone" label="手机号" prop="phone" align="center" />
<el-table-column key="address" label="住址" prop="address" align="center" />
<el-table-column key="zhiwei" v-if="!columnHideList['zhiwei']" label="职位" prop="zhiwei" align="center" class-name="column_visible" />
<el-table-column key="operationBtn" label="操作" align="center" width="120" class-name="operation_btn_wrap">
<template slot-scope="{row,column,$index}">
<el-button type="text" @click="download(row,$index)">下载</el-button>
<el-button type="text" @click="lookDetail(row,$index)">详情</el-button>
</template>
</el-table-column>
</trends-table>
// 获得列显示隐藏数据
getHideColist(item) {
this.columnHideList = item
this.$forceUpdate()//一定要强制更新视图
},
总结
感觉还有实现此类功能更好的方式方法,希望能一步步更好的优化。如有需要直接copy下来就可以直接使用。一些el-table的事件也增加了一部分,如有需要按照el-table的调用方式可以直接使用。