解决表头过多(20+)表格数据展示不直观的问题。
产品功能
1.隐藏不重要的表头
2.表头拖拽排序
3.可设置默认显示n个表头
4.自定义设置不可关闭的表头
实现效果
image.png实现代码
为了对组件的解耦故对组件进行了拆分
主页面
<template>
<div class="sc">
<sctable :productList="productList" :defaultColumns="defaultColumns">
<headerBtn
slot="customizeBtn"
:defaultColumns="defaultColumns"
@customizeHeader="(val) => (defaultColumns = val)"
></headerBtn>
</sctable>
</div>
</template>
<script>
export default {
components: {
headerBtn: require("./module/headerBtn.vue").default,
sctable: require("./module/table.vue").default,
},
props: {},
data() {
return {
productList: [
{
productNo: "产品编号",
customerProductNo: "客户产品编号",
name: "笔记本",
englishName: "macBook",
productLabel: "产品标签",
logisticsLabel: "物流标签",
productClassify: "产品分类",
salesman: "销售",
buyer: "采购",
tradeMode: "贸易方式",
}
],
//编辑后的表头
defaultColumns: [
{ label: "中文名称", prop: "name" },
{ label: "英文名称", prop: "englishName" },
{ label: "产品编号", prop: "productNo" },
{ label: "客户产品编号", prop: "customerProductNo" },
{ label: "产品标签", prop: "productLabel" },
{ label: "物流标签", prop: "logisticsLabel" },
{ label: "产品分类", prop: "productClassify" },
{ label: "销售", prop: "salesman" },
{ label: "采购", prop: "buyer" },
{ label: "贸易方式", prop: "tradeMode" },
],
};
},
};
</script>
<style lang="scss" scoped>
.sc /deep/ {
width: 1200px;
height: 800px;
background: #dcdfe6;
margin: 20px auto;
padding: 50px 10px;
.set_row {
text-align: right;
margin: 10px 0;
}
}
</style>
拖拽与动态显示(核心功能)
<template>
<div class="customize_btn">
<el-popover
placement="bottom-end"
popper-class="del_popover"
title="表头显示"
width="500"
trigger="click"
v-model="visible"
>
<el-divider content-position="center">拖拽排序</el-divider>
<div class="tag_show">
<ul class="tag_ul">
<li
class="tag_li"
:key="tag.label"
v-for="(tag, index) in beFacedHeader"
draggable
@dragenter="dragenter($event, index)"
@dragover="dragover($event, index)"
@dragstart="dragstart(index)"
>
{{ tag.label }}
<i
@click="handleClose(tag)"
v-if="notDeleteArr.indexOf(tag.prop) == -1 ? true : false"
class="el-icon-close"
></i>
</li>
</ul>
</div>
<el-divider v-if="newDefaultColumns.length" content-position="center"
>选至上方显示,选至下方不显示</el-divider
>
<div v-if="newDefaultColumns.length" class="tag_show">
<ul class="tag_ul">
<li
class="tag_li"
:key="index"
v-for="(tag, index) in newDefaultColumns"
>
{{ tag.label }}
<i
@click="handleCloseNew(tag)"
v-if="notDeleteArr.indexOf(tag.prop) == -1 ? true : false"
class="el-icon-close"
></i>
</li>
</ul>
</div>
<div style="overflow: hidden; margin: 0 5px" v-if="!isLiveUpdate">
<div style="float: left; margin: 0; display: inline-block">
<el-button
class="search_txt_btn"
size="mini"
type="text"
@click="reset"
>重置</el-button
>
</div>
<div style="float: right; margin: 0; display: inline-block">
<el-button
class="search_txt_btn"
size="mini"
type="text"
@click="visible = false"
>取消</el-button
>
<el-button
class="tile_btn"
type="primary"
size="mini"
@click="visible = false"
>确定</el-button
>
</div>
</div>
<div slot="reference" class="set_row">
<el-button class="set_btn" plain icon="el-icon-setting"
>列表设置</el-button
>
</div>
</el-popover>
</div>
</template>
<script>
export default {
props: {
// 是否实时更新
isLiveUpdate: {
type: Boolean,
default: true,
},
// 不可被关闭的收起的数组
notDeleteArr: {
type: Array,
default: () => ["productNo", "name"],
},
// 默认显示前5个表头
defaultHeaderLength: {
type: Number,
default: 5,
},
// 表头
defaultColumns: {
type: Array,
default: () => [],
},
},
data() {
return {
dragIndex: "", //当前拖拽的元素下标
visible: false,//浮窗状态
beFacedHeader: [],// 显示的表头集合
newDefaultColumns: [],//隐藏的表头集合
};
},
created() {
this.beFacedHeader = JSON.parse(JSON.stringify(this.defaultColumns));
// 默认只显示前 'defaultHeaderLength' 个表头
let arr1 = this.beFacedHeader.slice(0, this.defaultHeaderLength);
let arr2 = this.beFacedHeader.slice(
this.defaultHeaderLength,
this.beFacedHeader.length
);
this.beFacedHeader = arr1;
this.newDefaultColumns = arr2;
this.$emit("customizeHeader", this.beFacedHeader);
},
mounted() {},
methods: {
dragstart(index) {
this.dragIndex = index;
},
dragover(e, index) {
e.preventDefault();
},
dragenter(e, index) {
e.preventDefault();
// 避免源对象触发自身的dragenter事件
if (this.dragIndex !== index) {
const source = this.beFacedHeader[this.dragIndex];
this.beFacedHeader.splice(this.dragIndex, 1);
this.beFacedHeader.splice(index, 0, source);
// 排序变化后目标对象的索引变成源对象的索引
this.dragIndex = index;
this.$emit("customizeHeader", this.beFacedHeader);
}
},
// 显示的表头
handleClose(tag) {
this.beFacedHeader.splice(this.beFacedHeader.indexOf(tag), 1);
let newDefaultColumns = this.newDefaultColumns;
newDefaultColumns.push(tag);
this.newDefaultColumns = newDefaultColumns;
this.$emit("customizeHeader", this.beFacedHeader);
},
// 隐藏的表头
handleCloseNew(tag) {
this.newDefaultColumns.splice(this.newDefaultColumns.indexOf(tag), 1);
let beFacedHeader = this.beFacedHeader;
beFacedHeader.push(tag);
this.beFacedHeader = beFacedHeader;
this.$emit("customizeHeader", this.beFacedHeader);
},
},
};
</script>
<style lang="scss" scoped>
.customize_btn {
.set_btn {
background: #fff;
color: #000;
border: 1px solid #dcdfe6;
}
.set_btn:hover,
.set_btn:focus {
background: #fff;
color: #000;
border: 1px solid #dcdfe6;
}
}
.tag_ul {
list-style: none;
padding: 0;
.tag_li {
display: inline-block;
font-size: 12px;
background-color: #f4f4f5;
border-color: #e9e9eb;
color: #909399;
margin: 3px 5px;
height: 24px;
padding: 0 8px;
line-height: 22px;
border-radius: 4px;
border-width: 1px;
border-style: solid;
border-radius: 4px;
box-sizing: border-box;
white-space: nowrap;
.el-icon-close {
color: #909399;
border-radius: 50%;
text-align: center;
position: relative;
cursor: pointer;
font-size: 12px;
height: 16px;
width: 16px;
line-height: 16px;
vertical-align: middle;
top: 0px;
right: -5px;
transform: scale(0.8);
}
.el-icon-close:hover {
color: #fff;
background-color: #909399;
}
}
}
</style>
表格
<template>
<div class="sc_table">
<slot name="customizeBtn"></slot>
<el-table
ref="table"
:data="productList"
style="width: 100%"
highlight-current-row
class="primor_table_input table_sty"
:header-cell-style="header_style"
:row-style="tableRowStyle"
>
<el-table-column type="selection" fixed="left"></el-table-column>
<el-table-column
v-for="(item, index) in defaultColumns"
:key="index"
show-overflow-tooltip
:prop="item.prop"
:label="item.label"
:width="item.width"
:min-width="item.minWidth ? item.minWidth : '120'"
>
<template slot-scope="scope">
{{ scope.row[item.prop] }}
</template>
</el-table-column>
</el-table>
</div>
</template>
<script>
export default {
props: {
// 数据源
productList: {
type: Array,
default: () => [],
},
// 表头
defaultColumns: {
type: Array,
default: () => [],
},
},
};
</script>
网友评论