以下是使用React实现一个表格,并且表头可拖动调整列顺序以及点击表头进行排序的示例代码。我们将借助 react-dnd
库来实现表头的拖动功能,以及通过自定义的排序逻辑来处理表头点击排序。
首先,确保你的项目中已经安装了 react
、react-dnd
和 react-dnd-html5-backend
:
npm install react react-dnd react-dnd-html5-backend
以下是具体的代码实现:
import React, { useState, useEffect } from 'react';
import { DragDropContext, Draggable, Droppable } from 'react-dnd';
import { HTML5Backend } from 'react-dnd-html5-backend';
// 示例数据
const initialData = [
{ id: 1, name: 'John', age: 25, city: 'New York' },
{ id: 2, name: 'Jane', age: 30, city: 'Los Angeles' },
{ id: 3, name: 'Bob', age: 35, city: 'Chicago' }
];
// 表头配置
const initialColumns = [
{ id: 'name', label: 'Name', sortable: true },
{ id: 'age', label: 'Age', sortable: true },
{ id: 'city', label: 'City', sortable: true }
];
const Table = () => {
const [data, setData] = useState(initialData);
const [columns, setColumns] = useState(initialColumns);
const [isDragging, setIsDragging] = useState(false);
// 处理表头拖动开始
const handleDragStart = () => {
setIsDragging(true);
};
// 处理表头拖动结束
const handleDragEnd = () => {
setIsDragging(false);
};
// 处理表头拖动时的放置操作
const handleDrop = (result) => {
if (!result.destination) return;
const newColumns = Array.from(columns);
const [removed] = newColumns.splice(result.source.index, 1);
newColumns.splice(result.destination.index, 0, removed);
setColumns(newColumns);
};
// 处理表头点击排序
const handleSort = (columnId) => {
const sortedData = [...data].sort((a, b) => {
if (a[columnId] < b[columnId]) return -1;
if (a[columnId] > b[columnId]) return 1;
return 0;
});
setData(sortedData);
};
return (
<DragDropContext backend={HTML5Backend}>
<Droppable droppableId="columns">
{(provided) => (
<table>
<thead
ref={provided.innerRef}
{...provided.droppableProps}
style={{ cursor: isDragging? 'grabbing' : 'default' }}
>
<tr>
{columns.map((column, index) => (
<Draggable
key={column.id}
draggableId={column.id}
index={index}
>
{(provided) => (
<th
ref={provided.innerRef}
{...provided.dragHandleProps}
{...provided.draggableProps}
onClick={() => column.sortable && handleSort(column.id)}
style={{ cursor: 'pointer' }}
>
{column.label}
{isDragging && <span style={{ marginLeft: '5px' }}>⇄</span>}
</th>
)}
</Draggable>
))}
</tr>
</thead>
<tbody>
{data.map((row) => (
<tr key={row.id}>
{columns.map((column) => (
<td key={column.id}>{row[column.id]}</td>
))}
</tr>
))}
</tbody>
</table>
)}
</Droppable>
</DragDropContext>
);
};
export default Table;
在上述代码中:
- 首先定义了初始的数据
initialData
和表头的配置initialColumns
。 - 通过
useState
钩子来管理表格的数据、表头的列信息以及是否正在拖动表头的状态。 handleDragStart
、handleDragEnd
和handleDrop
函数分别处理表头拖动的开始、结束和放置操作,以实现表头列顺序的调整。handleSort
函数根据点击的表头列的id
,对表格数据进行相应的排序操作。- 在
return
语句中,使用react-dnd
的相关组件DragDropContext
、Draggable
和Droppable
来包裹表格的表头部分,以实现表头的拖动功能,同时在表头的th
元素上绑定了点击排序的逻辑。
请注意,这只是一个简单的示例,实际应用中可能需要根据具体需求进行更多的优化和扩展,比如处理更复杂的数据类型、添加样式等。