Modify the element-table yourself
Element’s Table component is well wrapped, but it can’t handle special needs. The project needed a header that could be dragged and dropped, so I came up with the idea that Element could use a slot to customize the header and manipulate it!
1. Project structure
For the Vue project (which will definitely install Element’s plugin), the template is shown below
<template>
<div class="table-container">
<el-table
:data="tableData"
height="250"
border
style="width: 100%"
>
<el-table-column
:key="h.prop"
v-for="h in tableHeaders"
:prop="h.prop"
:label="h.label"
header-align="center"
sortable
draggable="true"
>
<template slot="header" slot-scope="{ column }">
<span class="header-label" :id="h.prop">{{ column.label }}</span>
</template>
</el-table-column>
</el-table>
</div>
</template>
Copy the code
The script section is shown below, because it is adapting Element’s own components. So it is not practical to use the normal vue @ event listener, so we use native JS to implement (jquery is also ok, all manipulation dom library is ok, I personally lazy to use native).
<script>
export default {
name: "HelloWorld".methods: {
handleSortClick(e, column) {},
setCells() {
setTimeout(() = > {
let cells = document.querySelectorAll(".has-gutter th .cell");
cells.forEach((cell, index) = > {
cell.index = index;
cell.draggable = true;
cell.addEventListener("dragover".(e) = > {
e.preventDefault();
});
cell.addEventListener("dragleave".(e) = > {
e.target.style.border = "none";
});
cell.addEventListener("drop".(e) = > {
e.preventDefault();
let cell = e.path.find((p) = > p.className === "cell");
if(! cell) {return;
}
cell.style.border = "none";
if (this.target ! == cell) {let prop1 = this.target.children[0].id;
let prop2 = cell.children[0].id;
let index1 = this.tableHeaders.findIndex((h) = > h.prop === prop1);
let index2 = this.tableHeaders.findIndex((h) = > h.prop === prop2);
let temp = this.tableHeaders[index1];
this.tableHeaders[index1] = this.tableHeaders[index2];
this.tableHeaders[index2] = temp;
}
this.setCells();
this.kd = Date.now();
});
cell.addEventListener("dragenter".(e) = > {
let cell = e.path.find((p) = > p.className === "cell");
if(! cell) {return;
}
if (this.target ! == cell) {setTimeout(() = > {
if (this.target.index > cell.index) {
cell.style.borderLeft = "1px solid red";
} else {
cell.style.borderRight = "1px solid red"; }},0); }}); cell.addEventListener("dragstart".(e) = > {
// If the width is dragged, it will not trigger
if (document.body.style.cursor === "col-resize") {
this.target = {};
return;
}
setTimeout(() = > {
e.stopPropagation();
if (this.target.toString() === "{}") {
cell.style.backgroundColor = "#eee";
}
this.target = e.target;
}, 0);
});
cell.addEventListener("dragend".(e) = > {
cell.style.backgroundColor = "#fff";
e.target.style.border = "none";
});
cell.addEventListener("mousedown".(e) = > {});
});
}, 0);
},
contextmenu(column, event) {
event.preventDefault();
console.log(column, event);
let prop = column.property;
// let index = this.tableHeaders.findIndex(h=>h.prop===prop)
// this.tableHeaders.splice(index,1)}},mounted() {
this.setCells();
},
data() {
return {
target: {},
sortIndex: "0".kd: Date.now(),
tableHeaders: [{prop: "date".label: "Date" },
{ prop: "name".label: "Name" },
{ prop: "address".label: "Address"},].tableData: [{date: "2016-05-03".name: "Wang Xiaohu".address: Lane 1518, Jinshajiang Road, Putuo District, Shanghai}, {date: "2016-05-02".name: "Wang Xiaohu".address: Lane 1518, Jinshajiang Road, Putuo District, Shanghai}, {date: "2016-05-04".name: "Wang Xiaohu".address: Lane 1518, Jinshajiang Road, Putuo District, Shanghai}, {date: "2016-05-01".name: "Wang Xiaohu".address: Lane 1518, Jinshajiang Road, Putuo District, Shanghai}, {date: "2016-05-08".name: "Wang Xiaohu".address: Lane 1518, Jinshajiang Road, Putuo District, Shanghai}, {date: "2016-05-06".name: "Wang Xiaohu".address: Lane 1518, Jinshajiang Road, Putuo District, Shanghai}, {date: "2016-05-07".name: "Wang Xiaohu".address: Lane 1518, Jinshajiang Road, Putuo District, Shanghai,}]}; }}; </script>Copy the code
Here is the CSS part, which involves modifying the style of element, so I need /deep/, I am using SCSS preprocessor, if you need CSS, please change it yourself
<style lang="scss" scoped>
.table-container {
padding: 20px;
display: flex;
align-items: center;
justify-content: center;
.header-label {
padding: 10px 20px;
}
}
/deep/ .el-table th > .cell {
padding: 0;
}
/deep/ .el-table th {
padding: 0;
}
</style>
Copy the code