Статья начала мой личный блог:Оригинальная ссылка
учитьсяReact DnDПервоначальная причина заключалась в том, чтобы прочитать"Как написать компонент календаря с перетаскиванием"Когда я приложил исходный код, я не мог понять соответствующий код компонента React DnD с перетаскиванием, поэтому я очень энергично изучил компонент React DnD.
В этой статье объясняется, как использовать самое простое перетаскивание React DnD, показывая пример выбрасывания мусора (Box.jsx) в корзину (Dustbin.jsx) в корневом компоненте (Container.jsx).
предварительный просмотрэффект мусорного бака
ПроверятьИсходный код корзины
Основной API
Если вы хотите использовать его гибко, вам нужно сначала узнать несколько основных API.
- DragSourceИспользуется для обертывания компонента, который нужно перетащить, чтобы компонент можно было перетаскивать (сделать его перетаскиваемым)
- DropTargetИспользуется для переноса компонента, который получает перетаскиваемый элемент, чтобы компонент можно было перетащить на него.
-
DragDropContexИспользуется для обертывания корневого компонента перетаскивания,
DragSource
иDropTarget
нужно завернуть вDragDropContex
Внутри -
DragDropContextProviderи
DragDropContex
похоже наDragDropContextProvider
Элемент оборачивает корневой компонент перетаскивания.
После примерного понимания концепций этих API код для выбрасывания мусора (Box.jsx) в корзину (Dustbin.jsx) будет таким:
// Box.jsx
import { DragSource } from 'react-dnd';
@DragSource(type, spec, collect)
export default class Box {
/* ... */
}
// Dustbin.jsx
import { DropTarget } from 'react-dnd';
@DropTarget(types, spec, collect)
export default class Contaier {
/* ... */
}
// Contaier.jsx (DragDropContex)
import { DragDropContext } from 'react-dnd'
import HTML5Backend from 'react-dnd-html5-backend'
import Box from './Box';
import Dustbin from './Dustbin';
@DragDropContext(HTML5Backend)
export default class Contaier extends Component {
render() {
return (
<div>
<Dustbin/>
<Box/>
</div>
);
}
}
// 也可以写成 Contaier.jsx (DragDropContextProvider)
import { DragDropContextProvider } from 'react-dnd'
import HTML5Backend from 'react-dnd-html5-backend'
import Box from './Box';
import Dustbin from './Dustbin';
export default class DustbinContaier extends Component {
render() {
return (
<DragDropContextProvider backend = { HTML5Backend }>
<div>
<Dustbin/>
<Box/>
</div>
</DragDropContextProvider>
);
}
}
Введение в параметры API
код выше
@DragSource(type, spec, collect)
@DropTarget(types, spec, collect)
можно увидетьDragSource
, DropTarget
Есть три параметра:
- тип: тип перетаскивания, требуется
- spec: объект метода события перетаскивания, обязательный.
- собирать: вводить информацию, необходимую во время процесса перетаскивания, в реквизиты компонента и получать два параметра
connect
andmonitor
, обязательный.
Следующее соглашениеисходный компонентКомпонент, упакованный для DragSource (Box.jsx в этом примере),целевой компонентКомпонент, который является оболочкой для DropTarget (Dustbin.jsx в этом примере).
type
когдаsource组件
тип иtarget组件
Когда тип тот же,target组件
приемлемыйsource组件
.
Тип типа может быть строкой, символом или функцией для возврата других реквизитов компонента.
Переведено в код:
// ItemTypes.js 定义类型
export default {
BOX: 'box',
}
// Box.jsx
import ItemTypes from './ItemTypes'
@DragSource(ItemTypes.BOX, spec, collect)
// Dustbin.jsx
import ItemTypes from './ItemTypes'
@DropTarget(ItemTypes.BOX, spec, collect)
spec
spec определяет объект с помощью определенного метода, напримерsource组件
Спецификацию можно определитьтягасвязанные события,target组件
Спецификацию можно определитьместоСвязанные события, конкретный список:
DragSource specObj
-
beginDrag(props, monitor, component)
: событие срабатывает при начале перетаскивания,должен. Возвращает объект, связанный с реквизитом. -
endDrag(props, monitor, component)
: Событие запускается при перетаскивании концов, необязательно. -
canDrag(props, monitor)
: Является ли текущее перетаскиваемое событие необязательным. -
isDragging(props, monitor)
: событие, срабатывающее при перетаскивании, необязательно.
Переведено в код:
// Box.jsx
const sourceSpec = {
beginDrag(props, monitor, component){
// 返回需要注入的属性
return {
id: props.id
}
},
endDrag(props, monitor, component){
// ..
},
canDrag(props, monitor){
// ..
},
isDragging(props, monitor){
// ..
}
}
@DragSource(ItemTypes.BOX, sourceSpec, collect)
DropTarget specObj
-
drop(props, monitor, component)
Событие, возникающее при удалении компонента, необязательно. -
hover(props, monitor, component)
Событие, на которое отвечает компонент, когда он находится над DropTarget, необязательно. -
canDrop(props, monitor)
Событие, которое срабатывает, когда компонент может быть размещен, необязательно.
Переведено в код:
// Dustbin.jsx
const targetSpec = {
drop(props, monitor, component){
// ..
},
hover(props, monitor, component){
// ..
},
canDrop(props, monitor){
// ..
}
}
@DropTarget(ItemTypes.BOX, targetSpec, collect)
Параметры, связанные с методом объекта SpecObj
- props: текущий реквизит компонента
- монитор: Запросите текущее состояние перетаскивания, например, текущий перетаскиваемый элемент и его тип, текущее перетаскиваемое смещение и отбрасывается ли он в данный момент. Для получения информации о конкретных методах получения см.раздел монитора сбора параметров
-
source组件
Параметр монитораDragSourceMonitorэкземпляр -
target组件
Параметр монитораDropTargetMonitorэкземпляр
-
- компонент: текущий экземпляр компонента
collect
collect — это функция, которая по умолчанию принимает два параметра:connect
иmonitor
. Функция collect вернет объект, который будет внедрен в props компонента, то есть мы можем передатьthis.props
Получить все свойства, возвращаемые функцией collect.
подключение параметра
-
source组件
подключить в сбореDragSourceConnector, который имеет два встроенных метода:dragSource()
иdragPreview()
.dragSource()
вернуть метод, который будетsource组件
Передайте этот метод, чтобы соединить исходный DOM с бэкэндом React DnD;dragPreview()
Возвращает метод, в котором вы можете передать узел в качестве символа для предварительного просмотра перетаскивания. -
target组件
подключить в сбореDropTargetConnectorЭкземпляры встроенных методовdropTarget()
соответствоватьdragSource()
, который возвращает метод, который может подключить цель перетаскивания к серверной части React DnD.
Переведено в код:
// Box.jsx
@DragSource(ItemTypes.BOX, sourceSpec,(connect)=>({
connectDragSource: connect.dragSource(),
connectDragPreview: connect.dragPreview(),
}))
export default class Box {
render() {
const { connectDragSource } = this.props
return connectDragSource(
<div>
{
/* ... */
}
</div>,
)
}
}
// Dustbin.jsx
@DropTarget(ItemTypes.BOX, targetSpec, (connect)=>{
connectDropTarget: connect.dropTarget(),
})
export default class Dustbin {
render() {
const { connectDropTarget } = this.props
return connectDropTarget(
<div>
{
/* ... */
}
</div>,
)
}
}
монитор параметров
монитор используется для запроса текущего состояния перетаскивания, и его соответствующий экземпляр имеет множество встроенных методов.
-
source组件
Монитор в сборе естьDragSourceMonitorпример. -
target组件
Монитор в сборе естьDropTargetMonitorпример.
Список встроенных методов:
// DragSourceMonitor
monitor.canDrag() // 是否能被拖拽
monitor.isDragging() // 是否正在拖拽
monitor.getItemType() // 拖拽组件type
monitor.getItem() // 当前拖拽的item
monitor.getDropResult() // 查询drop结果
monitor.didDrop() // source是否已经drop在target
monitor.getInitialClientOffset() // 拖拽组件初始拖拽时offset
monitor.getInitialSourceClientOffset()
monitor.getClientOffset() // 拖拽组件当前offset
monitor.getDifferenceFromInitialOffset() // 当前拖拽offset和初始拖拽offset的差别
monitor.getSourceClientOffset()
// DropTargetMonitor
monitor.canDrop() // 是否可被放置
monitor.isOver(options) // source是否在target上方
monitor.getItemType() // 拖拽组件type
monitor.getItem() // 当前拖拽的item
monitor.getDropResult() // 查询drop结果
monitor.didDrop() // source是否已经drop在target
monitor.getInitialClientOffset() // 拖拽组件初始拖拽时offset
monitor.getInitialSourceClientOffset()
monitor.getClientOffset() // 拖拽组件当前offset
monitor.getDifferenceFromInitialOffset() // 当前拖拽offset和初始拖拽offset的差别
monitor.getSourceClientOffset()
конкретный пример
Во-первых, поскорее оставьте официальный пример и исходный код: