【Vue】如何写一个表格列显隐控制的组件?
需求
公司项目需要实现对表格列的显示隐藏进行配置,额外配置可自行添加,感觉这个组件挺泛用的,随便记录下。
这里只是说简单的显隐控制,复杂的只是在页面里面多写而已,核心代码是一样的。
简单的:
比较复杂的:
代码实现
表格页面.vue
<column-setup
@columnSetup="columnSetup"
:baseSelectedColumns="selectedColumns"
page="report"
></column-setup>
<el-table-column
prop="name"
label="Name"
width="auto"
v-if="isShowClumn('Name')"
show-overflow-tooltip
></el-table-column>
selectedColumns: [
{
displayName: 'Name',
show: true,
},
{
displayName: 'Email Address',
show: true,
},
{
displayName: 'Profile Type',
show: true,
},
{
displayName: 'User Type',
show: true,
},
],
columnSetup(selectedColumns) {
this.selectedColumns = selectedColumns
},
isShowClumn(name) {
let isShow
this.selectedColumns.forEach((item) => {
if (item.displayName === name) {
isShow = item.show
}
})
return isShow
},
组件.vue
样式请自行删减,有些是无用代码。
点击查看代码
<template>
<div class="table-custom-display">
<el-tooltip effect="dark" content="Columns" placement="top">
<el-popover
placement="bottom"
title=""
trigger="click"
v-model="visible"
popper-class="columns-popover"
@hide="close()"
@show="show"
>
<h2>Columns</h2>
<div class="top-check">
<el-input
placeholder="Search"
prefix-icon="el-icon-search"
v-model.trim="selectParam"
clearable
size="mini"
@input="search"
></el-input>
<div class="bot-check">
<template v-for="(item, index) in selectedColumns">
<div :key="item.name">
<el-checkbox
v-model="item.show"
:key="item.name"
checked
v-show="isShowItem(item, index)"
>
<div class="switch-defaults-name">
{{ item.displayName }}
</div>
</el-checkbox>
</div>
</template>
</div>
</div>
<div style="text-align: right; margin: 0" class="footer">
<el-button type="primary" size="mini" @click="done">
Done
</el-button>
<el-button size="mini" type="text" @click="visible = false">
Cancel
</el-button>
</div>
<el-button
type=""
size="medium"
icon="el-icon-setting"
style="font-size: 14px; margin-left: 10px; margin-top: 15px;"
slot="reference"
></el-button>
</el-popover>
</el-tooltip>
</div>
</template>
<script>
export default {
name: '',
props: {
baseSelectedColumns: {
type: Array,
default: () => {
return []
},
},
},
data() {
return {
buttons: sessionStorage.getItem('buttonPermissions'),
visible: false,
selectParam: '',
matchIndexArr: [],
initSelectedColumns:[],
selectedColumns: [],
}
},
watch: {
baseSelectedColumns: {
deep: true, // 深度监听
handler(newVal, oldVal) {
this.selectedColumns = JSON.parse(JSON.stringify(newVal))
},
},
},
mounted(){
this.selectedColumns = JSON.parse(JSON.stringify(this.baseSelectedColumns))
},
methods: {
close() {
this.visible = false
},
show(){
this.selectedColumns = JSON.parse(JSON.stringify(this.baseSelectedColumns))
},
done() {
let content = JSON.parse(JSON.stringify(this.selectedColumns))
this.visible = false
this.$emit('columnSetup', content)
},
search() {
this.matchIndexArr = []
this.selectedColumns.forEach((item, index) => {
let str = item.displayName.toLowerCase()
if (str.match(this.selectParam) !== null) {
this.matchIndexArr.push(index)
}
})
},
isShowItem(item, index) {
if (this.selectParam) {
return this.matchIndexArr.indexOf(index) !== -1
} else {
return true
}
},
},
}
</script>
<style scoped lang="scss">
::v-deep .el-checkbox__input.is-checked + .el-checkbox__label {
color: #596571 !important;
}
::v-deep .el-checkbox {
display: flex;
margin-right: 0;
}
::v-deep .el-checkbox__input,
.is-checked {
display: flex;
align-items: center;
}
::v-deep .el-checkbox__label {
/* background-color: red; */
width: 98%;
height: 30px;
}
::v-deep .el-switch.is-checked .el-switch__core {
border-color: #47bfaf !important;
background-color: #47bfaf !important;
}
.top-check {
// display: flex;
// align-content: center;
// justify-content: space-between;
.reset {
cursor: pointer;
font-size: 14px;
}
/deep/.el-tabs__item {
height: 28px;
line-height: 28px;
font-size: 18px;
padding: 0 20px !important;
color: #828282;
}
/deep/ .el-tabs__item:hover {
color: #828282 !important;
}
/deep/ .el-tabs__item.is-active {
color: #47bfaf !important;
}
/deep/ .el-input__inner {
border: 1px solid #1e384b !important;
color: #1e384b !important;
border-radius: 5px;
font-weight: 500;
height: 35px;
}
/deep/ .el-icon-circle-close {
color: #828282 !important;
margin-left: -20px;
line-height: 28px;
}
}
.bot-check {
margin-top: 10px;
height: 170px;
overflow-y: auto;
/deep/.el-checkbox__label {
padding: 5px 10px;
}
/deep/.el-link--inner {
padding: 10px 0;
}
.check-box {
display: flex;
flex-direction: column;
}
.system-check-box {
display: flex;
justify-content: space-between;
}
.switch-defaults-name {
max-width: 223px;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
}
.switch-system-name {
max-width: 183px;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
}
.label-wrapper {
margin: 14px 0;
display: flex;
&:nth-child(2) {
margin-top: 0;
}
.label-item {
display: flex;
align-items: center;
}
.label-text {
margin-left: 10px;
}
.label-switch {
flex-grow: 1;
justify-content: right;
}
}
}
.footer {
/deep/ .el-button--primary {
border-radius: 5px !important;
background-color: #47bfaf;
border-color: #47bfaf;
}
}
.table-custom-display {
}
</style>
<style>
.columns-popover {
background-color: #fff;
width: 300px;
}
.icon-popover {
background: #fff;
}
.columns-tootip {
z-index: 200000000000020 !important;
}
.switch-tootip .popper__arrow {
left: 40px !important;
}
</style>