React 之可伸縮列的表格

      網友投稿 1270 2025-04-01

      前言

      最近在項目中遇到了一個需求,客戶希望表格的列寬可以拖動伸縮。該項目的技術棧是 React + Ant Design 。后來看了文檔后進行了簡單的改動和封裝。以下將使用函數式組件,希望能對各位有所幫助,蟹蟹?(‘ω’)?。

      一、業務場景

      客戶希望表格的標題欄可以拖動來改變整列的寬窄,為了

      向別人裝x

      更方便的查看數據多的列,并增加表格組件的交互效果。

      二、實現思路

      Ant Design 文檔中已經明確給出了類式組件版本的 Demo ,此處在這個示例的基礎上進行修改,改為函數式組件,并對其進行封裝,提高其可復用性。此處奉上 官方文檔地址傳送門 。

      三、進行編碼

      1. 安裝依賴

      首先我們需要安裝依賴 react-resizable ,此依賴是實現該拖拽伸縮功能的核心。

      # npm 安裝 npm install react-resizable --save # yarn 安裝 yarn add react-resizable

      2. 重寫案例

      接下來我們將示例的類式寫法改為函數式。

      // 列表頁面 import { useState } from 'react'; import { Table } from 'antd'; import { Resizable } from 'react-resizable';// 核心依賴 import './resizable-title.css';// 此種引入方式不會在類名中添加哈希值,故僅作為替換樣式時使用 const ResizableTitle = ({ onResize, width, ...restProps }) => { if (!width) { return () }; return ( { e.stopPropagation() }} /> } onResize={onResize} draggableOpts={{ enableUserSelectHack: false }} > {/* 此處增加行內樣式目的:讓標題的文字不可選中 */} ); }; const List = () => { // 表格數據 const data = [ { key: 0, date: '2018-02-11', amount: 120, type: 'income', note: 'transfer', }, { key: 1, date: '2018-03-11', amount: 243, type: 'income', note: 'transfer', }, { key: 2, date: '2018-04-11', amount: 98, type: 'income', note: 'transfer', }, ]; // 列配置 const columns = [ { title: 'Date', dataIndex: 'date', width: 200, }, { title: 'Amount', dataIndex: 'amount', width: 100, sorter: (a, b) => a.amount - b.amount, }, { title: 'Type', dataIndex: 'type', width: 100, }, { title: 'Note', dataIndex: 'note', width: 100, }, { title: 'Action', key: 'action', render: () => Delete, } ]; // 用 useState 創建響應式數據 const [cols, setCols] = useState(columns); const colsArray = cols.map((col, index) => { return { ...col, onHeaderCell: column => ({ width: column.width, onResize: handleResize(index) }) }; }); // todo 調整列寬 const handleResize = index => { return (_, { size }) => { const temp = [...cols]; temp[index] = { ...temp[index], width: size.width }; setCols(temp); }; }; return (

      ); }; export default List;

      此處直接使用普通的 CSS ,單獨將控制伸縮列的樣式放到一個文件中,避免與其他樣式代碼沖突。頁面中其他樣式代碼可以單獨放入同目錄下的 index.less ,并用 import styles from './index.less' 方式引入。

      /* resizable-title.css */ /* 列表頁面 */ .react-resizable-handle { position: absolute; right: -5px; bottom: 0; z-index: 1; width: 10px; height: 100%; cursor: col-resize; }

      效果似乎還不錯,但是我們接下來還要對其進行封裝。

      3. 封裝復用

      為了提高復用性,我們需要把代碼封裝成一個公共組件。內部使用 Ant Design 的表格 Table 組件。

      // components/ResizableTable/index.jsx // 可拖拽表格組件 import { useState } from 'react'; import { Table } from 'antd'; import { Resizable } from 'react-resizable'; import './index.css'; const ResizableTitle = ({ onResize, width, ...restProps }) => { if (!width) { return (

      ) }; return ( { e.stopPropagation() }} /> } onResize={onResize} draggableOpts={{ enableUserSelectHack: false }} > ); }; const ResizableTable = ({ columns = [], ...props }) => { // * 列數據 const [cols, setCols] = useState(columns); const colsArray = cols.map((col, index) => { return { ...col, onHeaderCell: column => ({ width: column.width, onResize: handleResize(index) }) }; }); // todo 調整列寬 const handleResize = index => { return (_, { size }) => { const temp = [...cols]; temp[index] = { ...temp[index], width: size.width }; setCols(temp); }; }; return ( ); }; export default ResizableTable;

      // 列表頁面 import ResizableTable from '@/components/ResizableTable';// 可拖拽表格組件 const List = () => { // 表格數據 const data = [ // ... ]; // 列配置 const columns = [ // ... ]; return (

      ); }; export default List;

      /* components/ResizableTable/index.css */ .react-resizable-handle { position: absolute; right: -5px; bottom: 0; z-index: 1; width: 10px; height: 100%; cursor: col-resize; }

      4. 組件優化

      React 之可伸縮列的表格

      當然,僅僅封裝普通表格 Table 組件是不夠的,萬一想使用 ProComponents 中的超級表格組件 ProTable 呢。畢竟在后臺管理系統中, ProTable 的合理使用可以節省不少開發時間。同時也是為了讓該自定義組件更加完善,真正夠用且好用。

      // components/ResizableTable/index.jsx // 可拖拽表格組件 import { useState } from 'react'; import { Table } from 'antd'; import ProTable from '@ant-design/pro-table'; import { Resizable } from 'react-resizable'; import './index.css'; const ResizableTitle = ({ onResize, width, ...restProps }) => { if (!width) { return (

      • <blockquote id="kg8qy"><tfoot id="kg8qy"></tfoot></blockquote>
        <del id="kg8qy"></del>
        <tfoot id="kg8qy"><input id="kg8qy"></input></tfoot>
        • <th id="kg8qy"></th>
          ) }; return ( { e.stopPropagation() }} /> } onResize={onResize} draggableOpts={{ enableUserSelectHack: false }} > ); }; export const ResizableTable = ({ columns = [], ...props }) => { // * 列數據 const [cols, setCols] = useState(columns); const colsArray = cols.map((col, index) => { return { ...col, onHeaderCell: column => ({ width: column.width, onResize: handleResize(index) }) }; }); // todo 調整列寬 const handleResize = index => { return (_, { size }) => { const temp = [...cols]; temp[index] = { ...temp[index], width: size.width }; setCols(temp); }; }; return ( ); }; export const ResizableProTable = ({ columns = [], ...props }) => { // * 列數據 const [cols, setCols] = useState(columns); const colsArray = cols.map((col, index) => { return { ...col, onHeaderCell: column => ({ width: column.width, onResize: handleResize(index) }) }; }); // todo 調整列寬 const handleResize = index => { return (_, { size }) => { const temp = [...cols]; temp[index] = { ...temp[index], width: size.width }; setCols(temp); }; }; return ( ); }; // 默認暴露 普通表格 export default ResizableTable;

          // 列表頁面 // 可以使用"默認引入"和"模塊引入"兩種方式,此處使用模塊引入方式 import { ResizableTable, ResizableProTable } from '@/components/ResizableTable'; const List = () => { // 表格數據 const data = [ // ... ]; // 列配置 const columns = [ // ... ]; return ( <>

          普通表格 ResizableTable:


          超級表格 ResizableProTable:

          ); }; export default List;

          小結

          本次我們解決了 React 中表格標題行拖動伸縮的問題,同時也進行了公共組件的封裝與優化。不積跬步,無以至千里;不積小流,無以成江海。為了更好更強,我們需要不斷積累問題的解決方案,才能不斷進步。

          React web前端

          版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

          版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

          上一篇:【云駐共創】華為云數據庫之表與視圖(華為云 圖數據庫)
          下一篇:WPS辦公軟件有什么用?
          相關文章
          久久亚洲色WWW成人欧美| 亚洲va中文字幕无码久久不卡 | 亚洲人妖女同在线播放| 亚洲精品在线观看视频| 亚洲国产精品VA在线观看麻豆| 自拍偷自拍亚洲精品被多人伦好爽| 亚洲国产人成精品| 男人的天堂亚洲一区二区三区 | 亚洲精品国产精品乱码不卡| 久久亚洲精品高潮综合色a片| 亚洲经典千人经典日产| 亚洲精品自偷自拍无码| 亚洲av无码偷拍在线观看| 亚洲精品无码av中文字幕| 亚洲一本到无码av中文字幕| 亚洲熟妇无码八V在线播放| 亚洲综合av一区二区三区不卡 | 亚洲一级黄色大片| 国产精品亚洲综合五月天| 亚洲国产精品一区二区三区在线观看| 精品亚洲AV无码一区二区| 国产成人精品日本亚洲11| 亚洲中文无码亚洲人成影院| 亚洲色大成网站www尤物| 亚洲aⅴ无码专区在线观看春色| 亚洲AV无码专区在线厂| 亚洲精品无码激情AV| 亚洲一区二区精品视频| 亚洲熟妇av一区二区三区| 亚洲AV午夜福利精品一区二区| 亚洲av伊人久久综合密臀性色 | 99ri精品国产亚洲| 亚洲国产成人久久77| 日本亚洲精品色婷婷在线影院 | 亚洲成A人片777777| 91在线精品亚洲一区二区| 亚洲人成电影网站| 亚洲精品无码av片| 亚洲真人日本在线| 亚洲av无码国产精品夜色午夜 | 国产精品亚洲精品日韩动图|