react-sortable-hoc拖拽
安装
npm install react-sortable-hoc --save
代码如下(示例):
import React, { useImperativeHandle, forwardRef, memo, useState } from 'react';
import { DrawerForm } from '@ant-design/pro-form';
import { message, Select ,Table} from 'antd';
import { MenuOutlined } from '@ant-design/icons';
import { useUpdateEffect } from 'react-use';
// 核心代码
import { SortableContainer, SortableElement, SortableHandle } from 'react-sortable-hoc';
type ModalProps = {
ref?: React.MutableRefObject<SortTrackDrawerRefObject | undefined>;
onUpdated: () => void;
};
export type SortTrackDrawerRefObject = {
openModal: () => void;
};
// 定义拖拽的图标
const DragHandle = SortableHandle(() => <MenuOutlined style={{ cursor: 'move', color: '#999' }} />);
const columns = [
{
title: '排序',
align: 'center',
dataIndex: 'sort',
width: 30,
className: 'drag-visible',
render: () => <DragHandle />,
},
{
title: '音频名称',
dataIndex: 'name',
className: 'drag-visible',
},
];
const SortTrackDrawer: React.ForwardRefRenderFunction<SortTrackDrawerRefObject, ModalProps> = memo(
forwardRef((sProps, ref) => {
const [visible, setVisible] = useState<boolean>(false);
// 拖拽体
const SortableItem = SortableElement((props: any) => <tr {...props} />);
// 拖拽容器
const SortContainer = SortableContainer((props: any) => <tbody {...props} />);
// 拖拽时原列表替换
const arrayMoveMutable=(array: any[], fromIndex: number, toIndex: number) =>{
const startIndex = fromIndex < 0 ? array.length + fromIndex : fromIndex;
if (startIndex >= 0 && startIndex < array.length) {
const endIndex = toIndex < 0 ? array.length + toIndex : toIndex;
const [item] = array.splice(fromIndex, 1);
array.splice(endIndex, 0, item);
}
}
// 拖拽时返回新数组
const arrayMoveImmutable=(array: any[], fromIndex: number, toIndex: number) =>{
array = [...array];
arrayMoveMutable(array, fromIndex, toIndex);
return array;
}
// 拖拽后回调
const onSortEnd = ({ oldIndex, newIndex }:
{ oldIndex: number; newIndex: number }) => {
if (oldIndex !== newIndex) {
const newData = arrayMoveImmutable([...tableData], oldIndex, newIndex).filter((el) => !!el);
setTableData([...newData]);
}
};
// 获取表格数据
const getTableData = async () => {
try {
let res = [{
name:"测试13",
orderNum:1
uid:1,
}]
setTableData(res);
} finally {
}
};
// 确定按钮返回的数据
const handleFinish = async () => {
const uids = tableData.map((item) => item.uid);
console.log(uids)
message.success('排序已更新');
return true;
};
// 拖拽容器方法
const DraggableContainer = (props: any) => (
<SortContainer
useDragHandle
disableAutoscroll
helperClass="row-dragging"
onSortEnd={onSortEnd}
{...props}
/>
);
// 拖拽体方法
const DraggableBodyRow = (props: any) => {
const { className, style, ...restProps } = props;
const index = tableData.findIndex((x) => x.uid === restProps['data-row-key']);
return <SortableItem index={index} {...restProps} />;
};
// 进入组件加载数据
useUpdateEffect(() => {
getTableData();
}, [orderType]);
return (
<DrawerForm
width={isMobile ? '100%' : 520}
onVisibleChange={setVisible}
title={
<div className="sort-track-drawer-header">
<div>拖拽排序({tableData.length})</div>
</div>
}
visible={visible}
onFinish={handleFinish}
drawerProps={{ closable: false }}
submitter={{
searchConfig: {
submitText: '保存排序',
resetText: '取消',
},
}}
>
<Table
pagination={false}
dataSource={tableData}
columns={columns as any}
rowKey="uid"
size="small"
showHeader={false}
loading={loading}
components={{
body: {
wrapper: DraggableContainer,
row: DraggableBodyRow,
},
}}
/>
</DrawerForm>
);
}),
);
export default SortTrackDrawer;
效果如图: