相关文章推荐
难过的盒饭  ·  Canal ...·  2 周前    · 
刀枪不入的乌冬面  ·  java ...·  1 年前    · 
冷冷的马铃薯  ·  BigQuery ...·  1 年前    · 
豪气的荒野  ·  node.js - Redis ...·  1 年前    · 

难点


  • 如何与现有的自定义列、拖拽功能保持兼容。
  • 如何与现有的代码和接口数据结构保持兼容。
  • 拖动列宽的时候,如何阻止拖拽事件发生。
  • 其他边缘情况。

源码


// 添加onmousedown事件和样式
const ResizeableTitle = (props) => {
    const { width, onMouseDown, index, ...restProps } = props;
    if(!width) {
        return <th {...restProps} />;
    if(width.toString().indexOf('%') > -1) {
        return <th {...restProps} />;
    const propsClassName = `${restProps.className} react-resizable-th`;
    const className = 'react-resizable';
    const key = `react-${index}`;
    // 通过cloneElement,添加span标签
    return React.cloneElement(
        <th {...restProps} />,
            class: propsClassName,
            restProps.children,
                key={key}
                className={className}
                onMouseDown={onMouseDown}
                index={index}
                width={width}
                oldWidth={width}
this.newColums = (newColums) => {
    return newColums.map((col, index) => ({
        ...col,
        onHeaderCell: column => ({
            width: column.width,
            onMouseDown: this.onMouseDown,
            index
// 重新渲染列
components = {
    header: {
        cell: ResizeableTitle,
// 获取列宽
getColumnWidth = (columnNames) => {
    const widths = [];
    if(document.getElementsByTagName('colgroup').length > 0) {
        const children = document.getElementsByTagName('colgroup')[0].children;
        if(children.length > 0) {
            for(let i = 0, len = children.length; i < len; i++) {
                if(children[i].className != 'ant-table-expand-icon-col') {
                    widths.push({
                        key: columnNames[i],
                        width: Number(children[i].style.width.match(/[0-9]+/)[0])
    document.onmousemove = null;
    document.onmouseup = null;
    return widths;
// 获取table宽度、当前点击列宽、鼠标x轴位置
onMouseDown = (e) => {
    e.stopPropagation();
    e.preventDefault();
    const table = document.getElementsByTagName('table');
    if(table.length === 0) {
        return;
    if(!(table[0].getAttribute('style'))) {
        return;
    const colgroup = document.getElementsByTagName('colgroup');
    if(colgroup.length === 0 || colgroup.length < 2) {
        return;
    if(colgroup[0].children.length === 0) {
        return;
    const target = e.target;
    const width = Number(target.getAttribute('width'));
    const oldWidth = Number(target.getAttribute('oldWidth'));
    const tableWidth = Number(table[0].getAttribute('style').match(/[0-9]+/));
    this.nativeEventX = e.nativeEvent.x;
    this.onMouseMove(table, colgroup, target, width, oldWidth, tableWidth);
    this.onMouseUp();
 * @description 列宽拖动
 * @param table 表格
 * @param colgroup 表格
 * @param target 当前点击col
 * @param width col宽度        400px
 * @param oldWidth col宽度     400px 
 * @param tableWidth 表格宽度  400px
 * @memberof FilterWrap
onMouseMove = (table, colgroup, target, width, oldWidth, tableWidth) => {
    document.onmousemove = (e) => {
        let index = Number(target.getAttribute('index'));
        // 展开行特殊处理
        if(colgroup[0].children[0].className === 'ant-table-expand-icon-col') {
            index++;
        const col = colgroup[0].children[index];
        const col2 = colgroup[1].children[index];
        const currentX = (e.clientX) - this.nativeEventX;
        let newWidth;
        document.body.style.cursor = 'col-resize';
        newWidth = width + currentX;
        // 如果移动的距离小于原始宽度
        if(newWidth < oldWidth) {
            return;
        // 负数转换正数
        if(newWidth < 0) {
            newWidth = -(newWidth);
        const colWidth = `width: ${newWidth}px; min-width: ${newWidth}px`;
        const newTableWidth = `width: ${tableWidth + currentX}px;`;
        col.setAttribute('style', colWidth);
        col2.setAttribute('style', colWidth);
        table[0].setAttribute('style', newTableWidth);
        table[1].setAttribute('style', newTableWidth);
        target.setAttribute('width', `${newWidth}`);
onMouseUp = () => {
    document.onmouseup = () => {
        // 拖动结束,进行保存
        document.body.style.cursor = 'default';
        document.onmousemove = null;
        document.onmouseup = null;
        let params = {};
        const { columns } = this.state;
        const { pageId, actions } = this.props;
        const postData = this.getDataIndex(columns);
        params.type = pageId;
        params.columnNames = postData;
        params.columnWidth = this.getColumnWidth(postData);
        // 发起接口存储列数据
        actions && actions.updateCustomList(params);
                SAP UI5 响应式表格 sap.m.Table 根据不同宽度的屏幕动态决定显示或隐藏 Column 的实现源代码讲解试读版
            
SAP UI5 响应式表格 sap.m.Table 根据不同宽度的屏幕动态决定显示或隐藏 Column 的实现源代码讲解试读版
C/C++ Qt TableWidget 表格组件应用
TableWidget 表格结构组件,该组件可以看作是TreeWidget树形组件的高级版,表格组件相比于树结构组件灵活性更高,不仅提供了输出展示二维表格功能,还可以直接对表格元素直接进行编辑与修改操作,表格结构分为表头,表中数据两部分,表格结构可看作一个二维数组,通过数组行列即可锁定特定元素,如下代码是针对表格结构的基本使用方法,分别实现了表头数据的初始化,元素的插入等基本操作。