簡介
react-beautiful-dnd
基於react的一個組件庫,主要包含三個組件.
- DragDropContext : 用於包裝拖拽根組件,Draggable和Droppable都需要包裹在
DragDropContex
內 - Droppable 用於包裝你需要拖動的組件,使組件能夠被拖拽(make it draggable)
- Draggable 用於包裝接收拖拽元素的組件,使組件能夠放置(dropped on it)
API參數介紹
1. DragDropContext
爲了使用拖放功能,您需要將React
希望使用拖放功能的樹的部分包裝在中<DragDropContext />
。建議僅將整個應用程序包裝在<DragDropContext />
。**有嵌套<DragDropContext />
的是不支持的。**您將能夠達到你想要的條件拖放使用的道具<Droppable />
和<Draggable />
。您可以認爲<DragDropContext />
其目的與react-redux Provider組件相似。如果提供,則將內容安全保護隨機數屬性添加到注入的樣式標籤中。
1.1 編碼實戰
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>
);
}
}
1.2 參數
1.2.1 Props
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,
|};
1.2.2 參數列表
參數 | 是否必要 | 類型 | 說明 |
---|---|---|---|
onBeforeCapture | 否 | function | 在捕獲之前 |
onBeforeDragStart | 否 | function | 在拖動開始之前 |
onDragStart | 否 | function | 在拖動開始時 |
onDragUpdate | 否 | function | 在拖動變化時 |
onDragEnd | 是 | function | 在拖動結束時 |
1.3 總結
<DragDropContext />
是總體的包裝
<DragDropContext />
用於包裝拖拽根組件,Draggable和Droppable都需要包裹在DragDropContex內<DragDropContext />
不支持嵌套- 必須設置
<DragDropContext />
的onDragEnd鉤子函數(拖拽後的數組重新排序操作在這裏進行)
2. Droppable
<Droppable />
用於包裝你需要拖動的組件,使組件能夠被拖拽.
2.1 編碼實戰
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>;
2.2 參數
2.2.1 Droppable props
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';
2.2.2 參數列表
參數 | 是否必傳 | 數據類型 |
---|---|---|
droppableId | 是 | string |
type | 否 | string |
isDropDisabled | 否 | boolean |
isCombineEnabled | 否 | boolean |
direction | 否 | string |
ignoreContainerClipping | 否 | boolean |
mode | 否 | |
renderClone | 否 | |
getContainerForClone | 否 |
2.2.3 參數說明
- droppableId: 必要的參數
- type: 可用於僅接受指定的類。總是從定義它們的繼承type。 例如,如果您使用type=“person”,那麼它將只允許將類型“person”的放到自身上。type=‘task’的將不能被拖放到type爲‘person’的上。如果沒有提供類型,它將被設置爲“DEFAULT”。
- isDropDisabled: 一個控制列表中的所有拖放是否能夠被組合的標誌。它將默認爲false。
- direction : 項目流動的方向。選項有
"vertical"
(默認)和"horizontal"
。 - ignoreContainerClipping : 當
<Droppable />
在一個可滾動容器內,它的區域是受限制的,所以你只能在<Droppable />
的部分上,你可以看到。設置此道具可以避免這種行爲,允許您在<Droppable />
上的任何位置放下,即使它在視覺上被可滾動的父元素隱藏。默認的行爲適用於大多數情況,所以你可能永遠不需要使用這個道具,但是如果你有很長的<Draggable />
在一個短滾動容器中,它會很有用。請記住,如果在同一頁面上的滾動容器中有多個<Droppable />
,則可能會導致一些意想不到的行爲。 - mode :
standard
(默認) orvirtual
。 用於將列表指定爲虛擬列表。虛擬列表模式詳情參考官方文檔。 - renderClone : 用於在發生拖拽時渲染拖拽<可拖拽/>的克隆(替換)。有關使用細節,請參閱我們的reparenting指南。虛擬列表必須使用克隆。您可以不使用虛擬列表而使用克隆
- getContainerForClone : 在拖動過程中返回克隆的包含元素(父元素)的函數。請參閱我們的 reparenting guide 。
2.3 Droppable的子函數
<Droppable />
的React子節點必須是返回react元素的函數。
<Droppable droppableId="droppable-1">
{(provided, snapshot) => ({
/*...*/
})}
</Droppable>
該函數有兩個參數:
2.3.1 子函數的provided參數
2.3.1.1 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,
|};
2.3.1.2 參數說明
- provided.innerRef : 爲了使droppable正確運行,您必須綁定所提供的。innerRef指向ReactElement中儘可能高的DOM節點。這樣做是爲了避免使用ReactDOM查找DOM節點。
- provided.placeholder :用於在拖動過程中根據需要在< Droppable />中創建空格。當用戶拖動非主列表的列表時,需要此空間。請確保將佔位符放在您提供ref的組件中。我們需要增加本身的大小。
- provided.droppableProps (DroppableProps) :這是一個包含需要應用於可刪除元素的屬性的對象。它需要應用到與應用
provided.innerRef
相同的元素。它目前包含用於樣式化和查找的數據屬性。
2.3.1.3 編碼實戰
<Droppable droppableId="droppable-1">
{(provided, snapshot) => (
<div ref={provided.innerRef} {...provided.droppableProps}>
Good to go
{provided.placeholder}
</div>
)}
</Droppable>
2.3.2 子函數的snapshot參數
2.3.2.1 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,
|};
2.3.2.2 編碼實戰
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>
2.4 總結
-
<Droppable />
可以作爲<Draggable />
和<DragDropContext />
的子組件。 -
<Draggable />
必須包含在<Droppable />
中,即<Draggable />
只能作爲<Droppable />
的子組件
3. Draggable
<Draggable />
-用於包裝接收拖拽元素的組件,使組件能夠放置.
<Draggable />
組件可以被拖放到<Droppable />
上。<Draggable />
必須始終包含在< drop ppable />
中。可以對一個<Draggable />
在其父<Droppable />
內重新排序,或者移動到另一個<Droppable />
。這是可能的,因爲<Droppable />
可以自由地控制它允許什麼被丟棄在它上面。
每個<Draggable />
都有一個拖動句柄。拖動句柄是用戶爲了拖動<Draggable />
而與之交互的元素。一個拖動句柄可以是<Draggable />
元素本身,或者是<Draggable />
的子元素。注意,默認情況下,拖放句柄不能是交互元素,因爲事件處理程序在嵌套的交互元素上被阻塞。將可訪問性的適當語義添加到拖動句柄元素中。如果您希望使用交互式元素,必須設置disableInteractiveElementBlocking
。
3.1 編碼實戰
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>;
3.2 參數
3.2.1 Draggable Props
import type { Node } from 'react';
type Props = {|
// required
draggableId: DraggableId,
index: number,
children: DraggableChildrenFn,
// optional
isDragDisabled: ?boolean,
disableInteractiveElementBlocking: ?boolean,
shouldRespectForcePress: ?boolean,
|};
3.2.2 參數列表
參數 | 是否必傳 | 數據類型 |
---|---|---|
draggableId | 是 | string |
index | 是 | string |
isDragDisabled | 否 | boolean |
disableInteractiveElementBlocking | 否 | boolean |
shouldRespectForcePress | 否 | boolean |
3.2.3 參數說明
- draggableId :一個_需要_
DraggableId(string)
唯一標識的Draggable
爲應用程序. 請不要更改此 Props - 特別是在拖動時 - index: 一個需要number它與Draggable的順序相匹配在Droppable裏面. 它只是簡單的索引Draggable在列表中. 該index在一個內部需要是唯一的Droppable, 但不需要是唯一的Droppables. 通常情況下index價值將是簡單的index由Array.prototype.map函數提供; 必須唯一;必須連續。[0,1,2]而不是[1,2,8]
- isDragDisabled: 默認false,一個可選標誌,用於控制是否允許Draggable拖動
- disableInteractiveElementBlocking: 選擇退出以阻止來自交互式元素的拖動的標誌。欲瞭解更多信息,請參閱節內的交互式子元素
<Draggable />
- shouldRespectForcePress :拖動手柄是否應遵守強制按動交互。請參閱強制按下。
3.3 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;
該子函數包含三個參數
3.3.1 子函數的provided參數
3.3.1.1 provided: (DraggableProvided)
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.
3.3.1.2 參數說明
- provided.innerRef (innerRef: (HTMLElement) => void):爲了使
<Draggable />
正確運行,必須將innerRef函數綁定到ReactElement,您希望將其視爲<Draggable />
節點。這樣做是爲了避免使用ReactDOM查找DOM節點。 - provided.draggableProps: 這是一個包含數據屬性和內聯樣式的對象。此對象需要應用於將innerRef應用於的同一節點。它控制可拖動控件在拖動和不拖動時的移動。歡迎您添加自己的樣式到DraggableProps-style -但請不要刪除或替換任何屬性。
- provided.dragHandleProps: 這是用來拖動整個
<Draggable />
的。這個節點通常與<Draggable />
相同,但有時也可能是<Draggable />
的子節點。拖柄道具需要應用到您想要作爲拖柄的節點。這是一些需要應用到<Draggable />
節點的道具。最簡單的方法是將道具分散到可拖動節點上({…provider . draghandleprops})
。但是,如果你還需要回復他們,也歡迎你給這些道具打補丁。當isDragDisabled被設置爲true時,DragHandleProps將爲null。
3.3.2 子函數的snapshot參數
3.3.2.1 Snapshot: (DraggableStateSnapshot)
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,
|};
3.3.2.2 編碼實戰
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>
附錄
參考資料
相關文章
基於react-beautiful-dnd的一些拖拽示例-待完成
包含基礎使用示例,嵌套拖拽demo,拖拽投票demo
注意事項
此處中文註釋及參數說明均爲直譯,僅供參考,如有不理解之處儘量參考官方文檔