自己改造element-table
element的table组件封装很完善了,但遇到特殊需求却无能为力。
项目需要表头可以拖拽,于是想到element使用插槽可以自定义header,由此可以操控它!
1. 项目结构
vue的项目(肯定要装element的插件啦),template模板如下所示
<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>
复制代码
script 部分如下所示,因为是改造element自己的组件。所以使用常规的vue @事件监听就不现实了,所以咱们自己用原生的js来实现(jquery也可以,一切操作dom的库都行,我个人偷懒就直接用原生了)
<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 (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: "日期" },
{ prop: "name", label: "姓名" },
{ prop: "address", label: "地址" },
],
tableData: [
{
date: "2016-05-03",
name: "王小虎",
address: "上海市普陀区金沙江路 1518 弄",
},
{
date: "2016-05-02",
name: "王小虎",
address: "上海市普陀区金沙江路 1518 弄",
},
{
date: "2016-05-04",
name: "王小虎",
address: "上海市普陀区金沙江路 1518 弄",
},
{
date: "2016-05-01",
name: "王小虎",
address: "上海市普陀区金沙江路 1518 弄",
},
{
date: "2016-05-08",
name: "王小虎",
address: "上海市普陀区金沙江路 1518 弄",
},
{
date: "2016-05-06",
name: "王小虎",
address: "上海市普陀区金沙江路 1518 弄",
},
{
date: "2016-05-07",
name: "王小虎",
address: "上海市普陀区金沙江路 1518 弄",
},
],
};
},
};
</script>
复制代码
下面是css部分,涉及到修改element的样式,所以需要/deep/,我是用的scss预处理器,若需要css请自行更改
<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>
复制代码
2.效果
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END