关于antd protable/table(包含双表头)列宽拖动并缓存的处理方法单独封装为独立hooks

265 阅读2分钟

上一篇介绍了自定义的列宽拖动方法部分公共代码抽离

上一篇介绍了自定义的列宽拖动方法,后面嫌弃每个页面都写,挺麻烦的,所以抽离了部分公共代码,单独封装成了hooks,看此方法之前,请先阅读我前一篇文章。

好久没弄了,代码有点乱,我先上图片,代码可以直接赋值下面代码:

image.png

image.png

image.png

`import { useState, useEffect } from 'react';

const useResizableColumns = <T extends any[]>( initialColumns: T, storageKey: string, renderFunctions: Record<string, Function>, ) => { // 状态:列配置 const [columns, setColumns] = useState(initialColumns);

// 初始化:从 localStorage 中读取列配置,并重新绑定渲染逻辑 useEffect(() => { const storedColumns = localStorage.getItem(storageKey); if (storedColumns) { try { const parsedColumns = JSON.parse(storedColumns); // 重新绑定渲染逻辑 const columnsWithMethods = injectRenderFunctions(parsedColumns, renderFunctions); setColumns(columnsWithMethods as T); // 确保类型一致 } catch (error) { console.error('Failed to parse stored columns:', error); } } }, [storageKey, renderFunctions]);

const injectRenderFunctions = (cols: any[], renderFunctions: Record<string, Function>): any[] => { return cols.map((col) => { // 如果当前列有 children,递归处理子列 if (col.children) { return { ...col, children: injectRenderFunctions(col.children, renderFunctions), }; } // 如果当前列有对应的渲染逻辑,动态注入 if (renderFunctions[col.dataIndex || col.key]) { return { ...col, ...renderFunctionscol.dataIndex || col.key, }; } return col; }); };

const handleResize = (key: string) => (newWidth: number) => { setColumns((prevColumns) => { const updateColumns = (cols: any[]): any[] => { return cols.map((col) => { // 如果当前列的 key 匹配,更新宽度 if (col.key === key) { return { ...col, width: newWidth, }; } // 如果当前列有 children,递归处理子列 if (col.children) { return { ...col, children: updateColumns(col.children), }; } return col; }); }; const nextColumns = updateColumns([...prevColumns]); // 将更新后的列配置保存到 localStorage localStorage.setItem(storageKey, JSON.stringify(nextColumns)); return nextColumns as T; // 确保类型一致 }); };

const getMergedColumns = (cols: any[]): any[] => { return cols.map((col) => { // 如果当前列有 children,递归处理子列 if (col.children) { return { ...col, children: getMergedColumns(col.children), onHeaderCell: (column: any) => ({ width: column.width, onResize: handleResize(col.key) as any, }), }; } return { ...col, onHeaderCell: (column: any) => ({ width: column.width, onResize: handleResize(col.key) as any, }), }; }); };

// 返回处理后的列配置 return getMergedColumns(columns); };

export default useResizableColumns;`

/** *useResizableColumns

  • 自定义 Hook:用于实现列宽拖动功能,并支持动态注入渲染逻辑

  • @param initialColumns 初始列配置

  • @param storageKey 用于 localStorage 的 key

  • @param renderFunctions 包含渲染逻辑的对象

  • @returns 返回处理后的列配置(包含拖拽逻辑) */

    /**

    • 递归注入渲染逻辑injectRenderFunctions
    • @param cols 列配置
    • @param renderFunctions 渲染逻辑对象
    • @returns 返回注入渲染逻辑后的列配置 */

    /**

    • 处理列宽拖拽事件handleResize
    • @param key 列的 key
    • @returns 返回拖拽事件处理函数 / /* *getMergedColumns
    • 递归生成 mergedColumns,添加拖拽逻辑
    • @param cols 列配置
    • @returns 返回处理后的列配置 */ 好想有点乱啊,,,