700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > 快速实现一个table组件的拖拽排序功能(antd)

快速实现一个table组件的拖拽排序功能(antd)

时间:2021-07-26 18:07:32

相关推荐

快速实现一个table组件的拖拽排序功能(antd)

antd官方给的示例里引入了一堆三方库,写法更是花里胡哨,感到极其的繁琐,这了介绍一下自己实现的方法。(经过反馈官方已在.1月更新了新的demo,现在优雅了很多,不喜欢三方库的同学可以看看以下纯原生写法)

方法封装

const onRow = (state: [], setState: any) => ({draggable: true,style: { cursor: 'move' },onDragStart: (ev: any) => {ev.dataTransfer.effectAllowed = 'move';ev.dataTransfer.setData('text', ev.target.getAttribute('data-row-key'));},onDragEnter: (ev: any) => {const nodes = ev.target.parentNode.childNodes;nodes.forEach((item: any) => (item.style.borderTop = '2px dashed #1890ff'));},onDragLeave: (ev: any) => {const nodes = ev.target.parentNode.childNodes;nodes.forEach((item: any) => (item.style.borderTop = ''));},onDrop: (ev: any) => {ev.preventDefault();ev.stopPropagation();const dragId = Number(ev.dataTransfer.getData('text'));const dropCol =ev.target.tagName !== 'TR' ? ev.target.parentNode : ev.target;// dropCol.parentNode.insertBefore(dragCol, dropCol); // DOM操作const dropId = Number(dropCol.getAttribute('data-row-key'));const dragIndex = state.findIndex((item: any) => item.id === dragId); // 注意这里的idconst dropIndex = state.findIndex((item: any) => item.id === dropId);const data = [...state];const item = data.splice(dragIndex, 1); // 移除data.splice(dropIndex, 0, item[0]); // 插入setState(data);dropCol.childNodes.forEach((item: any) => (item.style.borderTop = ''));},onDragOver: (ev: any) => ev.preventDefault(),});

方法使用

<TablerowKey="id"dataSource={query}pagination={false}onRow={() => onRow(query, setQuery)}><Table.Columntitle="查询条件"dataIndex="label"/></Table>

其他代码

const [query, setQuery] = useState<any>([]);

说明

antd的table组件有个onRow字段,该字段就是表格对应的tr标签。

首先开启draggable属性让元素可以拖拽,在onDragStart里使用事件对象的dataTransfer.setData方法记录拖拽元素的data-row-key,这个key即在table组件设置的rowKey,要保证其唯一性;在onDrop里使用getData读取拖拽元素的key,通过移除和插入更新数组的顺序重新render;在onDragOver阻止浏览器的默认事件。三个拖拽事件相互配合即可轻松快速的完成一款纯天然的拖拽效果,无需引入其它三方库。

onDragEnter和onDragLeave用来添加一些交互展示效果,也可以不用。

另外需要注意:

在onDrop方法中获取dragIndex和dropIndex时,比较时的字段需要和Table的rowKey一致。比如你的rowKey是uid,那么就要写成const dragIndex = state.findIndex((item:any) => item.uid === dragId)。

如果你的单元格里嵌套了多个元素,那么获取dropCol就要使用递归写法,一直找到tagName为TR为止。const dropCol = ev.target.tagName !== 'TR' ? ev.target.parentNode : ev.target

在实际生产中还需要更严谨一点,比如判断是否放在拖动元素上,以及向下拖拽插入时,需要记录clientY并和放置的元素的clientY进行比较,来决定样式加borderTop还是bordeBottom等。

文章原文:快速实现一个antd的table组件的拖拽排序功能/post/7181679788774391863

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。