1.纵向组件拖拽
import React, { useState } from 'react';
import { DragDropContext, Droppable, Draggable } from 'react-beautiful-dnd';
//初始化数据
const getItems = (count) =>
Array.from({ length: count }, (v, k) => k).map((k) => ({
id: `item-${k + 1}`,
content: `content ${k + 1}`,
}));
// 重新记录数组顺序
const reorder = (list, startIndex, endIndex) => {
const result = Array.from(list);
const [removed] = result.splice(startIndex, 1);
result.splice(endIndex, 0, removed);
return result;
};
const grid = 8;
// 设置样式
const getItemStyle = (isDragging, draggableStyle) => ({
// some basic styles to make the items look a bit nicer
userSelect: 'none',
padding: grid * 2,
margin: `0 0 ${grid}px 0`,
// 拖拽的时候背景变化
background: isDragging ? 'lightgreen' : '#ffffff',
// styles we need to apply on draggables
...draggableStyle,
});
const getListStyle = () => ({
background: 'black',
padding: grid,
width: 250,
});
const modalList2 = [
{
id: '1sdas',
content: '你好1',
placeholder: '',
},
{
id: '2weqw',
content: '你好2',
placeholder: '',
},
{
id: '3xczxc',
content: '你好3',
placeholder: '',
},
{
id: '4sdas',
content: '你好4',
placeholder: '',
},
{
id: '5fsafas',
content: '你好5',
placeholder: '',
},
];
const ReactBeautifulDnd = () => {
const [items, setItems] = useState(modalList2);
const onDragEnd = (result) => {
if (!result.destination) {
return;
}
const itemContent = reorder(
items,
result.source.index,
result.destination.index,
);
setItems(itemContent);
};
return (
<DragDropContext onDragEnd={onDragEnd}>
<div>
<Droppable droppableId="droppable">
{(provided, snapshot) => (
<div
//provided.droppableProps应用的相同元素.
{...provided.droppableProps}
// 为了使 droppable 能够正常工作必须 绑定到最高可能的DOM节点中provided.innerRef.
ref={provided.innerRef}
style={getListStyle(snapshot)}
>
{items.map((item, index) => (
<Draggable key={item.id} draggableId={item.id} index={index}>
{(provided, snapshot) => (
<div
ref={provided.innerRef}
{...provided.draggableProps}
{...provided.dragHandleProps}
key={item.id}
style={getItemStyle(
snapshot.isDragging,
provided.draggableProps.style,
)}
>
{item.content}
</div>
)}
</Draggable>
))}
{provided.placeholder}
</div>
)}
</Droppable>
</div>
</DragDropContext>
);
};
export default ReactBeautifulDnd;
2.横向拖拽
const getListStyle = () => ({
background: 'black',
display: 'flex',
padding: grid,
overflow: 'auto',
});
<Droppable droppableId="droppable" direction="horizontal"></Droppable>
与纵向拖拽相比,多了dispaly:"flex",direction="horizontal"
3.代办事项拓展
多个Droppable(横向纵向拖拽)
3.1初始数据源todoData
const initialData = {
tasks: {
'task-1': { id: 'task-1', content: '吃饭' },
'task-2': { id: 'task-2', content: '睡觉' },
'task-3': { id: 'task-3', content: '打豆豆' },
'task-4': { id: 'task-4', content: 'coding' }
},
columns: {
'column-1': {
id: 'column-1',
title: 'TODO',
taskIds: ['task-1', 'task-2', 'task-3', 'task-4']
},
'column-2': {
id: 'column-2',
title: 'TODOING',
taskIds: []
},
'column-3': {
id: 'column-3',
title: 'FINISH',
taskIds: []
}
},
columnOrder: ['column-1', 'column-2', 'column-3']
}
export default initialData
3.2DragDropContext
import React, { useState } from 'react';
import { DragDropContext } from 'react-beautiful-dnd';
import initialData from './todoData.js';
import Column from './column.js';
const ReactBeautifulTodo = () => {
const [state, setState] = useState(initialData);
const onDragEnd = (result) => {
const { destination, source, draggableId } = result;
if (!destination) {
return;
}
if (
destination.droppableId === source.droppableId &&
destination.index === source.index
) {
return;
}
const start = state.columns[source.droppableId];
const finish = state.columns[destination.droppableId];
if (start === finish) {
const newTaskIds = Array.from(start.taskIds);
newTaskIds.splice(source.index, 1);
newTaskIds.splice(destination.index, 0, draggableId);
const newColumn = {
...start,
taskIds: newTaskIds,
};
const newState = {
...state,
columns: {
...state.columns,
[newColumn.id]: newColumn,
},
};
setState(newState);
return;
}
const startTaskIds = Array.from(start.taskIds);
startTaskIds.splice(source.index, 1);
const newStart = {
...start,
taskIds: startTaskIds,
};
const finishTaskIds = Array.from(finish.taskIds);
finishTaskIds.splice(destination.index, 0, draggableId);
const newFinish = {
...finish,
taskIds: finishTaskIds,
};
const newState = {
...state,
columns: {
...state.columns,
[newStart.id]: newStart,
[newFinish.id]: newFinish,
},
};
setState(newState);
};
return (
<DragDropContext onDragEnd={onDragEnd}>
<div style={{ display: 'flex' }}>
{state.columnOrder.map((columnId) => {
const column = state.columns[columnId];
const tasks = column.taskIds.map((taskId) => state.tasks[taskId]);
return <Column key={column.id} column={column} tasks={tasks} />;
})}
</div>
</DragDropContext>
);
};
export default ReactBeautifulTodo;
3.2多项任务Droppable
import React from 'react';
import Task from './task';
import { Droppable } from 'react-beautiful-dnd';
import styles from './index.less';
// 设置样式
const getItemStyle = (isDraggingOver) => ({
padding: '8px',
transition: 'background-color 0.2s ease',
flexGrow: '1',
minHeight: '100px',
background: isDraggingOver ? 'skyblue' : 'white',
});
const Column = (props) => {
return (
<div className={styles.Container}>
<h3 className={styles.Title}>{props.column.title}</h3>
<Droppable droppableId={props.column.id} type="TASK">
{(provided, snapshot) => (
<div
ref={provided.innerRef}
{...provided.droppableProps}
isdraggingover={snapshot.isDraggingOver.toString()}
style={getItemStyle(snapshot.isDraggingOver)}
>
{props.tasks.map((task, index) => (
<Task key={task.id} task={task} index={index} />
))}
{provided.placeholder}
</div>
)}
</Droppable>
</div>
);
}
export default Column
.Container {
margin: 8px;
border: 1px solid lightgrey;
border-radius: 2px;
width: 220px;
display: flex;
flex-direction: column;
}
.Title {
padding: 8px;
}
3.3拖拽项Draggable
import React from 'react';
import { Draggable } from 'react-beautiful-dnd';
const getItemStyle = (snapshot) => {
return {
border: '1px solid lightgrey',
borderRadius: '2px',
padding: '8px',
marginBottom: '8px',
transition: 'backgroundColor 0.2s ease',
backgroundColor: snapshot.isDragging ? 'lightgreen' : 'white',
};
};
const Task = (props) => {
return (
<Draggable
draggableId={props.task.id}
index={props.index}
>
{(provided, snapshot) => {
return (
<div
{...provided.draggableProps}
{...provided.dragHandleProps}
ref={provided.innerRef}
isdragging={snapshot.isDragging.toString()}
>
<div style={getItemStyle(snapshot)}>{props.task.content}</div>
</div>
);
}}
</Draggable>
);
};
export default Task;
拖拽不生效时,首先看数据是否正确,再排除样式问题,在Task.js中,添加样式不能和ref的div放在一起,需要重新写一个。只是暂时找到问题,原理不知