antDesign
推荐的 4 种可拖动组件
名称 | start | Unpacked Size | 说明 |
---|---|---|---|
react-beautiful-dnd | 24.4K | 1.39 MB | |
react-dnd | 16.2K | 673 kB | |
react-sortable-hoc | 9.5K | 798 kB | ProComponents 的 Table 例子用到 |
dnd-kit | 2.2K | 732 kB |
react-beautiful-dnd
react-dnd
antDesign
中dnd
的例子给了很多拖动的例子,用了不同的组件,这点很烦人。
上传列表拖拽排序使用 itemRender
,我们可以集成 react-dnd
来实现对上传列表拖拽排序。
可以拖动table
中的行,antDesign
给出了两种实现方式
以上两个实现方式的源代码,可以在例子文档中获得。
react-dnd
名称 | 推荐程度 | 说明 |
---|---|---|
react-beautiful-dnd | ☆☆☆ | 代码比较复杂,放弃 |
react-dnd | ☆☆☆☆☆ | 侵入性小,代码简洁 |
react-sortable-hoc | ☆☆ | 功能单一,只能作为排序,但是使用起来简单 |
dnd-kit | ☆ | 用的人不多,放弃 |
react-beautiful-dnd
排名第一的拖拽组件,所以要研究以下。
安装与使用
# yarntyarn add react-beautiful-dndtyarn add array-moveimport { DragDropContext } from 'react-beautiful-dnd';import arrayMove from 'array-move';
安装 types 依赖
tyarn add @types/react-beautiful-dnd -D
react-beautiful-dnd-multi-list-typescript-example
删除依赖
tyarn remove react-beautiful-dndtyarn remove @types/react-beautiful-dnd -D
例子代码,这个代码要保留下来,因为里面记录了具体的使用方法。
import React from 'react';// 拖拽组件相关的引用import { DragDropContext, Droppable, Draggable } from 'react-beautiful-dnd';import type {DraggingStyle,NotDraggingStyle,DropResult,DroppableProvided,DroppableStateSnapshot,} from 'react-beautiful-dnd/index';import type { CSSProperties } from 'react';const grid = 8;/*** 水平样式* @param isDragging* @param draggableStyle* @returns*/const getItemStyle = (isDragging: boolean,draggableStyle: DraggingStyle | NotDraggingStyle | undefined,): CSSProperties | undefined => ({// 基本的设置userSelect: 'none',padding: grid * 2,margin: `0 ${grid}px 0 0`,// 拖动时改变背景颜色background: isDragging ? 'lightgreen' : 'grey',// 可拖动时的样式...draggableStyle,});/*** 得到列表的样式* @param isDraggingOver* @returns*/const getListStyle = (isDraggingOver: boolean) => ({background: isDraggingOver ? 'lightblue' : 'lightgrey',display: 'flex',padding: grid,overflow: 'auto',});interface ItemType {id: string;content: string;}export default () => {const [items, SetItems] = React.useState<ItemType[]>([{ id: 'item-0', content: 'hello' },{ id: 'item-1', content: 'I' },{ id: 'item-2', content: 'am' },{ id: 'item-3', content: '卡' },{ id: 'item-4', content: '特' },{ id: 'item-5', content: '洛' },]);// a little function to help us with reordering the result/*** 重新排序的函数* @param list 要排序的数组* @param startIndex* @param endIndex* @returns*/const reOrder = (list: ItemType[], startIndex: number, endIndex: number) => {const result = Array.from(list);// 得到要删除的元素const [removed] = result.splice(startIndex, 1);// 将删除的元素添加到 endIndexresult.splice(endIndex, 0, removed);return result;};/*** 拖动结束事件* @param result*/const onDragEnd = (result: DropResult): void => {// 拖动到列表以外了if (!result.destination) {return;}console.log(result);const newItems = reOrder(items,result.source.index,result.destination.index,);SetItems(newItems);};return (<div className="App"><DragDropContext onDragEnd={onDragEnd}>{/* 可以落下的区域 */}<Droppable droppableId="imgList" direction="horizontal">{(provided: DroppableProvided, snapshot: DroppableStateSnapshot) => {console.log(provided, snapshot);return (<divref={provided.innerRef}style={getListStyle(snapshot.isDraggingOver)}{...provided.droppableProps}>{items.map((item, index) => (/** 可拖动组件 */<Draggable key={item.id} draggableId={item.id} index={index}>{(provided, snapshot) => (<divref={provided.innerRef}{...provided.draggableProps}{...provided.dragHandleProps}style={getItemStyle(snapshot.isDragging,provided.draggableProps.style,)}>{item.content}</div>)}</Draggable>))}{provided.placeholder}</div>);}}</Droppable></DragDropContext></div>);};