背景
在 element-plus
中,如果有大数据列表展示,我们通常会使用虚拟表格Virtualized Table
实现,但是这个虚拟表格并不支持拖动改变列宽。本次我们就是要实现这个虚拟表格的拖动改变列宽的功能。
效果预览
思路
- 通过
headerCellRenderer
选项,添加一个1px的边,用于拖拽。 - 通过
ondragstart
和ondragend
给这个边添加拖动事件,通过对比拖动前后的距离来进行改变当前列宽度
代码
复制到代码里就可以直接预览,注意: 用了less
<template>
<el-table-v2 :columns="columns" :data="data" :width="700" :height="400" />
</template>
<script lang="jsx" setup>
import { ref } from "vue";
const dataGenerator = () => ({
name: "张三",
address: "上海市xxxx街道xxxx弄xxxx号",
desc: "这是一个描述这是一个描述这是一个描述",
});
const columns = ref([
{
key: "name",
dataKey: "name",
align: "center",
width: 150,
headerCellRenderer: () => (
<div
class="header-box"
ondragenter={(e) => e.preventDefault()}
ondragover={(e) => e.preventDefault()}
>
<div>姓名</div>
<div
class="drag-line"
draggable
ondragstart={(e) => dragStart(e)}
ondragend={(e) => dragEnd(e, "name")}
></div>
</div>
),
cellRenderer: ({ cellData: name }) => <div class="row">{name}</div>,
},
{
key: "address",
dataKey: "address",
align: "center",
width: 150,
headerCellRenderer: () => (
<div
class="header-box"
ondragenter={(e) => e.preventDefault()}
ondragover={(e) => e.preventDefault()}
>
<div>家庭地址</div>
<div
class="drag-line"
draggable
ondragstart={(e) => dragStart(e)}
ondragend={(e) => dragEnd(e, "address")}
></div>
</div>
),
cellRenderer: ({ cellData: address }) => <div class="row">{address}</div>,
},
{
key: "desc",
dataKey: "desc",
width: 150,
align: "center",
headerCellRenderer: () => (
<div
class="header-box"
ondragenter={(e) => e.preventDefault()}
ondragover={(e) => e.preventDefault()}
>
<div>描述</div>
<div
class="drag-line"
draggable
ondragstart={(e) => dragStart(e)}
ondragend={(e) => dragEnd(e, "desc")}
></div>
</div>
),
cellRenderer: ({ cellData: desc }) => <div class="row">{desc}</div>,
},
]);
const data = ref(Array.from({ length: 200 }).map(dataGenerator));
// 拖动改变列宽相关逻辑
const columnRefresh = (x, fileKey) => {
let columnItem = columns.value.find((item) => item.dataKey === fileKey) || {};
columnItem.width = columnItem.width + x;
};
let x1, x2;
var dragStart = (e) => {
x1 = e.x;
};
var dragEnd = (e, fileKey) => {
x2 = e.x;
let x = x2 - x1;
columnRefresh(x, fileKey);
};
</script>
<style lang="less">
.header-box {
position: relative;
flex: 1;
.drag-line {
position: absolute;
top: -9px;
right: -8px;
bottom: -9px;
cursor: ew-resize;
width: 1px;
padding-left: 6px;
border-right: 1px solid #d8d8d8;
background: transparent;
}
}
.row {
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
}
</style>