Antd中使用Table集成 react-resizable实现可伸缩列

发布于:2025-07-18 ⋅ 阅读:(20) ⋅ 点赞:(0)

需求:需要实现可自定义拖拽宽度的Table列表

官方文档:集成 react-resizable 来实现可伸缩列。

 

问题

直接安装npm install react-resizable --save

会直接报错

ERROR  Failed to compile with 1 errors                                                                                                                                                 17:25:56
 error  in ./node_modules/react-draggable/build/cjs/Draggable.js

Module parse failed: Unexpected token (210:22)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
|   // the underlying DOM node ourselves. See the README for more information.
|   findDOMNode() /*: ?HTMLElement*/{
>     return this.props?.nodeRef?.current ?? _reactDom.default.findDOMNode(this);
|   }
|   render() /*: ReactElement<any>*/{

 @ ./node_modules/react-draggable/build/cjs/cjs.js 6:4-26
 @ ./node_modules/react-resizable/build/Resizable.js
 @ ./node_modules/react-resizable/index.js

 在查阅网上内容后  把问题定位在安装的 react-resizable版本兼容上  因为当前公司项目使用的是Antd3.x    偏老的项目

兼容版本

依赖库 推荐版本 说明
antd 3.x (如 3.26.20) Ant Design 3.x 主版本
react-resizable 1.x (如 1.11.1) 支持 React 16+,与 Antd 3.x 兼容
react-draggable 4.x (如 4.4.5) react-resizable@1.x 的 peerDependency

问题解决 | 安装命令

npm install antd@3.x react-resizable@1.11.1 react-draggable@4.4.5

完整步骤

1. 确保 react-resizable 的样式文件被正确引入

react-resizable 需要手动引入其 CSS 样式文件,否则拖拽手柄会不可见。
在代码顶部添加以下引入语句

import "react-resizable/css/styles.css"; // 必须引入!

如果使用 Umi.js,确保样式文件能被 Webpack 正确处理。如果仍然不生效,可以尝试在 global.less 中直接复制样式内容:

/* global.less */
.react-resizable {
  position: relative;
}
.react-resizable-handle {
  position: absolute;
  width: 10px;
  height: 100%;
  bottom: 0;
  right: -5px;
  cursor: col-resize;
  background: transparent;
  z-index: 1;
}
.react-resizable-handle:hover {
  background: #eee;
}

2. 检查 react-resizable 和 react-draggable 的版本

Antd 3.x 需要配合 react-resizable@1.x 和 react-draggable@4.x,版本过高可能导致兼容性问题。
安装指定版本

npm install react-resizable@1.11.1 react-draggable@4.4.5

3. 确认 Umi.js 的配置

如果样式仍未生效,可能是 Umi.js 的 CSS 加载顺序问题。
在 Umi 的配置文件(如 .umirc.ts)中检查以下配置:

export default {
  // 确保 CSS 相关 loader 配置正确
  cssLoader: {
    modules: {
      localIdentName: '[local]', // 避免样式被哈希化
    },
  },
  // 如果需要,显式注入样式
  styles: ['https://unpkg.com/react-resizable@1.11.1/css/styles.css'],
};

4. 检查 DOM 结构是否正确

在浏览器开发者工具中检查 <th> 元素是否包含 react-resizable-handle 子元素:

  • 如果存在但不可见,说明样式未生效(回到步骤 1)。

  • 如果根本不存在,说明 Resizable 组件未正确渲染(检查版本或代码逻辑)。


5. 完整代码修正示例

import React from "react";
import { Table } from "antd";
import { Resizable } from "react-resizable";
import "react-resizable/css/styles.css"; // 关键!确保引入样式

const ResizableTitle = (props) => {
  const { onResize, width, ...restProps } = props;
  return (
    <Resizable
      width={width}
      height={0}
      onResize={onResize}
      draggableOpts={{ enableUserSelectHack: false }}
    >
      <th {...restProps} />
    </Resizable>
  );
};

class Demo extends React.Component {
  state = {
    columns: [
      { title: "Date", dataIndex: "date", width: 200 },
      { title: "Amount", dataIndex: "amount", width: 100 },
      { title: "Type", dataIndex: "type", width: 100 },
      { title: "Note", dataIndex: "note", width: 100 },
      { title: "Action", key: "action", render: () => <a>Delete</a> },
    ],
  };

  components = {
    header: {
      cell: ResizableTitle,
    },
  };

  handleResize = (index) => (e, { size }) => {
    this.setState(({ columns }) => {
      const nextColumns = [...columns];
      nextColumns[index] = { ...nextColumns[index], width: size.width };
      return { columns: nextColumns };
    });
  };

  render() {
    const columns = this.state.columns.map((col, index) => ({
      ...col,
      onHeaderCell: (column) => ({
        width: column.width,
        onResize: this.handleResize(index),
      }),
    }));

    return (
      <Table
        bordered
        components={this.components}
        columns={columns}
        dataSource={this.data}
      />
    );
  }
}

export default Demo;

在 global.less 或你的全局样式文件中,添加以下 CSS:

/* 覆盖 react-resizable 默认的斜向拖动手柄 */
.react-resizable-handle {
  position: absolute;
  width: 10px !important;       /* 调整手柄宽度 */
  height: 100% !important;      /* 手柄高度和表头一致 */
  bottom: 0;
  right: -5px;                  /* 让手柄稍微超出列边界 */
  cursor: col-resize !important; /* 列调整光标 */
  background-color: transparent !important;
  z-index: 1;
}

/* 鼠标悬停时显示手柄 */
.react-resizable-handle:hover {
  background-color: #f0f0f0 !important;
}

/* 确保表头单元格可以触发拖拽 */
.react-resizable {
  position: relative !important;
}

 


最终效果

 

 


网站公告

今日签到

点亮在社区的每一天
去签到