react-beautiful-dnd
基于react的一个组件库,主要包含三个组件.
DragDropContext
内为了使用拖放功能,您需要将React
希望使用拖放功能的树的部分包装在中<DragDropContext />
。建议仅将整个应用程序包装在<DragDropContext />
。**有嵌套<DragDropContext />
的是不支持的。**您将能够达到你想要的条件拖放使用的道具<Droppable />
和<Draggable />
。您可以认为<DragDropContext />
其目的与react-redux Provider组件相似。如果提供,则将内容安全保护随机数属性添加到注入的样式标签中。
import React from 'react';
import { DragDropContext } from 'react-beautiful-dnd';
class App extends React.Component {
onBeforeCapture = () => {
/*...*/
};
onBeforeDragStart = () => {
/*...*/
};
onDragStart = () => {
/*...*/
};
onDragUpdate = () => {
/*...*/
};
onDragEnd = () => {
// the only one that is required
};
render() {
return (
<DragDropContext
onBeforeCapture={this.onBeforeCapture}
onBeforeDragStart={this.onBeforeDragStart}
onDragStart={this.onDragStart}
onDragUpdate={this.onDragUpdate}
onDragEnd={this.onDragEnd}
>
<div>Hello world</div>
</DragDropContext>
);
}
}
type Responders = {|
// optional
onBeforeCapture?: OnBeforeCaptureResponder
onBeforeDragStart?: OnBeforeDragStartResponder,
onDragStart?: OnDragStartResponder,
onDragUpdate?: OnDragUpdateResponder,
// required
onDragEnd: OnDragEndResponder,
|};
import type { Node } from 'react';
type Props = {|
...Responders,
// We do not technically need any children for this component
children: Node | null,
// Read out by screen readers when focusing on a drag handle
dragHandleUsageInstructions?: string,
// Used for strict content security policies
nonce?: string,
// Used for custom sensors
sensors?: Sensor[],
enableDefaultSensors?: ?boolean,
|};
参数 | 是否必要 | 类型 | 说明 |
---|---|---|---|
onBeforeCapture | 否 | function | 在捕获之前 |
onBeforeDragStart | 否 | function | 在拖动开始之前 |
onDragStart | 否 | function | 在拖动开始时 |
onDragUpdate | 否 | function | 在拖动变化时 |
onDragEnd | 是 | function | 在拖动结束时 |
<DragDropContext />
是总体的包装<DragDropContext />
用于包装拖拽根组件,Draggable和Droppable都需要包裹在DragDropContex内<DragDropContext />
不支持嵌套<DragDropContext />
的onDragEnd钩子函数(拖拽后的数组重新排序操作在这里进行)<Droppable />
用于包装你需要拖动的组件,使组件能够被拖拽.
import { Droppable } from 'react-beautiful-dnd';
<Droppable droppableId="droppable-1" type="PERSON">
{(provided, snapshot) => (
<div
ref={provided.innerRef}
style={{ backgroundColor: snapshot.isDraggingOver ? 'blue' : 'grey' }}
{...provided.droppableProps}
>
<h2>I am a droppable!</h2>
{provided.placeholder}
</div>
)}
</Droppable>;
import type { Node } from 'react';
type Props = {|
// required
droppableId: DroppableId,
// optional
type?: TypeId,
mode?: DroppableMode,
isDropDisabled?: boolean,
isCombineEnabled?: boolean,
direction?: Direction,
ignoreContainerClipping?: boolean,
renderClone?: DraggableChildrenFn,
getContainerForClone?: () => HTMLElement,
children: (DroppableProvided, DroppableStateSnapshot) => Node,
|};
type DroppableMode = 'standard' | 'virtual';
type Direction = 'horizontal' | 'vertical';
参数 | 是否必传 | 数据类型 |
---|---|---|
droppableId | 是 | string |
type | 否 | string |
isDropDisabled | 否 | boolean |
isCombineEnabled | 否 | boolean |
direction | 否 | string |
ignoreContainerClipping | 否 | boolean |
mode | 否 | |
renderClone | 否 | |
getContainerForClone | 否 |
"vertical"
(默认)和 "horizontal"
。<Droppable />
在一个可滚动容器内,它的区域是受限制的,所以你只能在<Droppable />
的部分上,你可以看到。设置此道具可以避免这种行为,允许您在<Droppable />
上的任何位置放下,即使它在视觉上被可滚动的父元素隐藏。默认的行为适用于大多数情况,所以你可能永远不需要使用这个道具,但是如果你有很长的<Draggable />
在一个短滚动容器中,它会很有用。请记住,如果在同一页面上的滚动容器中有多个<Droppable />
,则可能会导致一些意想不到的行为。standard
(默认) or virtual
。 用于将列表指定为虚拟列表。虚拟列表模式详情参考官方文档。<Droppable />
的React子节点必须是返回react元素的函数。
<Droppable droppableId="droppable-1">
{(provided, snapshot) => ({
/*...*/
})}
</Droppable>
该函数有两个参数:
provided: (DroppableProvided)
import type { Node } from 'react';
type DroppableProvided = {|
innerRef: (?HTMLElement) => void,
droppableProps: DroppableProps,
placeholder: ?Node,
|};
type DroppableProps = {|
// used for shared global styles
'data-rbd-droppable-context-id': ContextId,
// Used to lookup. Currently not used for drag and drop lifecycle
'data-rbd-droppable-id': DroppableId,
|};
provided.innerRef
相同的元素。它目前包含用于样式化和查找的数据属性。<Droppable droppableId="droppable-1">
{(provided, snapshot) => (
<div ref={provided.innerRef} {...provided.droppableProps}>
Good to go
{provided.placeholder}
</div>
)}
</Droppable>
snapshot: (DroppableStateSnapshot)
type DroppableStateSnapshot = {|
// Is the Droppable being dragged over?
// Is the Droppable being dragged over?
isDraggingOver: boolean,
// What is the id of the draggable that is dragging over the Droppable?
// Is the Droppable being dragged over?
draggingOverWith: ?DraggableId,
// What is the id of the draggable that is dragging from this list?
// Useful for styling the home list when not being dragged over
// What is the id of the draggable that is dragging from this list?
// Useful for styling the home list when not being dragged over
draggingFromThisWith: ?DraggableId,
// Whether or not the placeholder is actively being used.
// This is useful information when working with virtual lists
// (See our virtual list pattern)
// Whether or not the placeholder is actively being used.
// This is useful information when working with virtual lists
// (See our virtual list pattern)
isUsingPlaceholder: boolean,
|};
children函数还提供了与当前拖动状态相关的少量状态。这可以选择性地用于增强组件。一个常见的用例是在拖动<Droppable />
时改变其外观。
<Droppable droppableId="droppable-1">
{(provided, snapshot) => (
<div
ref={provided.innerRef}
style={{ backgroundColor: snapshot.isDraggingOver ? 'blue' : 'grey' }}
{...provided.droppableProps}
>
I am a droppable!
{provided.placeholder}
</div>
)}
</Droppable>
<Droppable />
可以作为<Draggable />
和<DragDropContext />
的子组件。
<Draggable />
必须包含在<Droppable />
中,即<Draggable />
只能作为<Droppable />
的子组件
<Draggable />
-用于包装接收拖拽元素的组件,使组件能够放置.
<Draggable />
组件可以被拖放到<Droppable />
上。<Draggable />
必须始终包含在< drop ppable />
中。可以对一个<Draggable />
在其父<Droppable />
内重新排序,或者移动到另一个<Droppable />
。这是可能的,因为<Droppable />
可以自由地控制它允许什么被丢弃在它上面。
每个<Draggable />
都有一个拖动句柄。拖动句柄是用户为了拖动<Draggable />
而与之交互的元素。一个拖动句柄可以是<Draggable />
元素本身,或者是<Draggable />
的子元素。注意,默认情况下,拖放句柄不能是交互元素,因为事件处理程序在嵌套的交互元素上被阻塞。将可访问性的适当语义添加到拖动句柄元素中。如果您希望使用交互式元素,必须设置disableInteractiveElementBlocking
。
import { Draggable } from 'react-beautiful-dnd';
<Draggable draggableId="draggable-1" index={0}>
{(provided, snapshot) => (
<div
ref={provided.innerRef}
{...provided.draggableProps}
{...provided.dragHandleProps}
>
<h4>My draggable</h4>
</div>
)}
</Draggable>;
import type { Node } from 'react';
type Props = {|
// required
draggableId: DraggableId,
index: number,
children: DraggableChildrenFn,
// optional
isDragDisabled: ?boolean,
disableInteractiveElementBlocking: ?boolean,
shouldRespectForcePress: ?boolean,
|};
参数 | 是否必传 | 数据类型 |
---|---|---|
draggableId | 是 | string |
index | 是 | string |
isDragDisabled | 否 | boolean |
disableInteractiveElementBlocking | 否 | boolean |
shouldRespectForcePress | 否 | boolean |
DraggableId(string)
唯一标识的Draggable
为应用程序. 请不要更改此 Props - 特别是在拖动时<Draggable />
<Draggable/>
的React子节点必须是返回react元素的函数。
<Draggable draggableId="draggable-1" index={0}>
{(provided, snapshot) => (
<div
ref={provided.innerRef}
{...provided.draggableProps}
{...provided.dragHandleProps}
>
Drag me!
</div>
)}
</Draggable>
type DraggableChildrenFn = (
DraggableProvided,
DraggableStateSnapshot,
DraggableRubric,
) => Node;
该子函数包含三个参数
type DraggableProvided = {|
innerRef: (HTMLElement) => void,
draggableProps: DraggableProps,
// will be null if the draggable is disabled
dragHandleProps: ?DragHandleProps,
|};
For more type information please see our types guide.
<Draggable />
正确运行,必须将innerRef函数绑定到ReactElement,您希望将其视为<Draggable />
节点。这样做是为了避免使用ReactDOM查找DOM节点。<Draggable />
的。这个节点通常与<Draggable />
相同,但有时也可能是<Draggable />
的子节点。拖柄道具需要应用到您想要作为拖柄的节点。这是一些需要应用到<Draggable />
节点的道具。最简单的方法是将道具分散到可拖动节点上({…provider . draghandleprops})
。但是,如果你还需要回复他们,也欢迎你给这些道具打补丁。当isDragDisabled被设置为true时,DragHandleProps将为null。type DraggableStateSnapshot = {|
// Set to true if a Draggable is being actively dragged, or if it is drop animating
// Both active dragging and the drop animation are considered part of the drag
// *Generally this is the only property you will be using*
isDragging: boolean,
// Set to true if a Draggable is drop animating. Not every drag and drop interaction
// as a drop animation. There is no drop animation when a Draggable is already in its final
// position when dropped. This is commonly the case when dragging with a keyboard
isDropAnimating: boolean,
// Information about a drop animation
dropAnimation: ?DropAnimation
// What Droppable (if any) the Draggable is currently over
draggingOver: ?DroppableId,
// the id of a draggable that you are combining with
combineWith: ?DraggableId,
// if something else is dragging and you are a combine target, then this is the id of the item that is dragging
combineTargetFor: ?DraggableId,
// There are two modes that a drag can be in
// 'FLUID': everything is done in response to highly granular input (eg mouse)
// 'SNAP': items snap between positions (eg keyboard);
mode: ?MovementMode,
|};
children函数还提供了与当前拖动状态相关的少量状态。这可以选择性地用于增强组件。一个常见的用例是在拖动<Draggable />
时改变它的外观。注意:如果你想把光标变成像grab这样的东西,你需要把拖拽样式添加进去。(参见扩展上面的“DraggableProps-style”)
<Draggable draggableId="draggable-1" index={0}>
{(provided, snapshot) => {
const style = {
backgroundColor: snapshot.isDragging ? 'blue' : 'grey',
...provided.draggableProps.style,
};
return (
<div
ref={provided.innerRef}
{...provided.draggableProps}
{...provided.dragHandleProps}
style={style}
>
Drag me!
</div>
);
}}
</Draggable>
包含基础使用示例,嵌套拖拽demo,拖拽投票demo
此处中文注释及参数说明均为直译,仅供参考,如有不理解之处尽量参考官方文档