vue3+elementplus虚拟表el-table-v2官方只实现一些基本功能,如排序、固定列、合并组(列、行)等,没有像el-table一样实现拖拉列宽。自己仿el-table实现拖拉列宽(只实现拖拉列宽,不是拖拽换列功能)。如果另外要实现拖拽换列功能,可看看以下,例子是el-table 的guolaopi/element-plus-table-dragable-demo,通过element-plus-table-dragable实现,也可以用在el-table-v2上试试,我这暂时没有尝试。
1.实现拖拉列宽的原理(仿el-tabel)
鼠标按下mousedown时记录鼠标开始位置event.clientX,并生成代理resize line(一条和表格等高并在当前元素left+2px位置生成);
鼠标移动mousemove时,只改变resize line的left位置,不改变表格数据(性能好一些)
鼠标抬起mouseup时,改变表格列位置,并删除代理resize line
2.使用技术技巧
封装函数resizeColumns,并在组件数据渲染完后调用,并传入列数据(columns);
使用vue3 h()函数,生成代理resize line
3.问题难点
如何在列头宽度改变的同时,改变表格数据的列宽?
一开始,是通过获取表格列头,鼠标移动时列头宽度改变后,同时改变列表数据列的宽度,这样做会出现很多问题:
问题1:拖拉列宽后,再拖拉滚动条,表体部分和表头混乱(element-plus得el-tabel-v2 scroll方法导致)
解决在el-tabel-v2 scroll方法上加上防抖和节流(会跟着变,但是会抖动且还是会有一定的错乱)
问题2:表头固定后,无法mouseover从而无法拖拉列宽,或者拖拉完成移出表头移动到表体后,表格拖拉过的列宽又还原了
拖拉前:flex: 0 0 auto; width: 100px; border: 0.5px solid rgba(235, 238, 245, 0.6); cursor: e-resize; left: 434.5px;
拖拉后:flex: 0 0 auto; width: 135px; border: 0.5px solid rgba(235, 238, 245, 0.6); cursor: e-resize; left: 435.5px;
鼠标移入表格表体后:flex: 0 0 auto; width: 135px; border: 0.5px solid rgba(235, 238, 245, 0.6); cursor: e-resize; left: 435.5px;
问题出现原因:主要由于设置固定后(可以固定在左边或者右边),elementplus底层将表格分成不同div进行显示了,控制的不再是一个div里面的数据
固定列后整个数据表的结构如下,这就导致,表格列头宽度改变后,根本或者难以控制表格数据列宽度也跟着变化
el-table-v2__main
el-vl__wrapper el-table-v2__body
.firstChild.firstChild .el-table-v2__row(所有行)
el-table-v2__row-cell--placeholder
el-table-v2__row-cell
el-table-v2__header-wrapper
el-table-v2__header
el-table-v2__header-row el-table-v2__dynamic-header-row
el-table-v2__header-row-cell--placeholder
el-table-v2__header-cell
el-table-v2__header-cell-text
el-table-v2__left
...结构同上
el-table-v2__right
...结构同上</