# 表格拖拽调整列宽度

表格通过拖拽来调整列的宽度

ElementUI Table自带参数resizeable实现了该功能,一起来看看是如何实现的吧

首先ElementUI Table拖拽时会有一条竖线显示

image-20230830221141865

其对应的dom结构如下

image-20230830221218958

而鼠标hover到div的边框上时,鼠标样式发生变化,具体是通过style内联样式变化的

image-20230830221435279

在ElementUI 代码中是如下实现的

handleMouseMove(event, column) {
      if (column.children && column.children.length > 0) return;
      let target = event.target;
  		// 找到事件对象th
      while (target && target.tagName !== 'TH') {
        target = target.parentNode;
      }

      if (!column || !column.resizable) return;
			// ElTable border属性为true且没有在移动时
      if (!this.dragging && this.border) {
        // 获取事件对象的DOMRect对象
        let rect = target.getBoundingClientRect();

        const bodyStyle = document.body.style;
        // 当鼠标位于th的边框上时,给body添加上‘col-resize’样式
        if (rect.width > 12 && rect.right - event.pageX < 8) {
          bodyStyle.cursor = 'col-resize';
          if (hasClass(target, 'is-sortable')) {
            target.style.cursor = 'col-resize';
          }
          this.draggingColumn = column;
        } else if (!this.dragging) {
          bodyStyle.cursor = '';
          if (hasClass(target, 'is-sortable')) {
            target.style.cursor = 'pointer';
          }
          this.draggingColumn = null;
        }
      }
    },
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31

# 为什么修改col元素而不是th元素

在实现表格列宽度可以拖拽改变的功能时,通常会使用 colgroup 元素内的 col 元素来控制列的宽度,而不是直接修改 th 元素的宽度。这是因为这种方法有一些重要的优势:

  1. 性能优化:当您直接修改 th 元素的宽度时,浏览器会重新渲染整个表格,包括重新布局和绘制所有的单元格,这可能导致性能下降,尤其是在大型表格中。使用 col 元素可以更精确地控制列的宽度,从而避免不必要的重绘操作,提高性能。
  2. 维护性:使用 col 元素可以更容易维护表格的结构。如果您需要更改列的宽度,只需更新 col 元素的宽度属性,而不必更改每个 th 元素的宽度。这使得代码更易于管理和维护。
  3. 兼容性:一些浏览器对于直接修改 th 元素的宽度支持不一致,而使用 col 元素的方法更有可能在各种浏览器中获得一致的行为。
  4. 支持跨表格样式:在一些情况下,您可能需要在一个页面上使用多个表格,并且希望表格的样式保持一致。使用 col 元素可以更容易实现这种跨表格的一致性。

这种方法有助于提高性能、减少重绘操作,并提供更好的维护性和可移植性。