react-beautiful-dnd(2)简单demo测试

640 阅读2分钟

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;

demo1.gif

2.横向拖拽

    const getListStyle = () => ({
      background: 'black',
      display: 'flex',
      padding: grid,
      overflow: 'auto',
    });
    <Droppable droppableId="droppable" direction="horizontal"></Droppable>

与纵向拖拽相比,多了dispaly:"flex",direction="horizontal"

demo2.gif

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放在一起,需要重新写一个。只是暂时找到问题,原理不知

demo3.gif

转载:www.jianshu.com/p/ba19292cd…