vue3+elementplus虚拟表实现拖拉列宽

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
...结构同上

你可能感兴趣的:(vue.js,前端,elementplus)