基于React-beautiful-dnd实现单列表和多列表直接拖拽

1、下载所需要的依赖

yarn add react-beautiful-dnd

2、页面使用

import { Image, List } from '这里使用公司组件库,可使用ant desgin'
import React, { useState } from 'react'
import { DragDropContext, Draggable, Droppable, DropResult, } from 'react-beautiful-dnd'
import { users, users1 } from './users'  // mork数据
export default () => {
  const [list, setList] = useState(users)
  const [list1, setList1] = useState(users1)
  // 处理同列表之间的数据
  const reorder = (list: any, startIndex: number, endIndex: number) => {
    const result = Array.from(list)
    const [removed] = result.splice(startIndex, 1)
    result.splice(endIndex, 0, removed)
    return result
  }
  // 处理不同列表之间的数据 removeList需要删除的数组,newList为添加的数组,result拖拽的元素信息,identification进行赋值的标识判断
  const onResultChange = (removeList: any, newList: any, result: any, identification?: any) => {
    removeList.forEach((item: any, index: any) => {
      if (item.id === result.draggableId) {
        newList.splice(result.destination.index, 0, item)
      }
    })
    removeList.splice(result.source.index, 1)
  // 根据identification标识进行列表赋值,渲染视图。如出现更多列表自行处理需求,可根据标识
    setList(identification ? [...newList] : [...removeList])
    setList1(identification ? [...removeList] : [...newList])
  }
  // 拖拽结束后的回调
  const onDragEnd = (result: any) => {
    if (!result.destination) return // 判断是否有结束参数
    if (result.destination.droppableId !== result.source.droppableId) { // 结束的id不等于开始的id,说明是两个列表直接发生了变化 也可以添加多个列表,droppableId不一致,在以下进行判断
    // 以下只是两个列表的交互,如果是多个,要增加更多判断,标识也需自行替换处理需求,最好将开始和结束的droppableId传递
      if (result.destination.droppableId === "droppable1") { //  第一个列表拖拽到了第二个列表
        onResultChange(list, list1, result, false)
      } else {  //  第二个列表拖拽到了第一个列表
        onResultChange(list1, list, result, true)
      }
    } else { //  id位置相等,说明是同列表直接的数据发生了变化
      if (result.source.droppableId === "droppable") {
        const newList: any = reorder(list, result.source.index, result.destination.index)
        setList([...newList])
      } else {
        const newList: any = reorder(list1, result.source.index, result.destination.index)
        setList1([...newList])
      }
    }
  }
  return (
    <List>
      <div>第一个列表</div>
      <DragDropContext onDragEnd={onDragEnd}>
        <Droppable droppableId='droppable'>  // 每个容器的ID不能一致
          {droppableProvided => (
            <div ref={droppableProvided.innerRef}>
              {list.map((item: any, index: number) => ( // 循环的数组
                <Draggable key={item.id} draggableId={item.id} index={index}> //  key draggableId是唯一性
                  {(provided, snapshot) => (
                    <div
                      ref={provided.innerRef}
                      {...provided.draggableProps}
                      {...provided.dragHandleProps}
                      style={{
                        ...provided.draggableProps.style,
                        opacity: snapshot.isDragging ? 0.8 : 1,
                      }}
                    >
                      <List.Item
                        key={item.name}
                        prefix={
                          <Image
                            src={item.avatar}
                            style={{ borderRadius: 24 }}
                            fit='cover'
                            width={48}
                            height={48}
                          />
                        }
                      >
                        {item.name}
                      </List.Item>
                    </div>
                  )}
                </Draggable>
              ))}
              {droppableProvided.placeholder}
            </div>
          )}
        </Droppable>
        <div>第二个列表</div>
        <Droppable droppableId='droppable1'>
          {droppableProvided1 => (
            <div ref={droppableProvided1.innerRef}>
              {list1.map((item: any, index: number) => (
                <Draggable key={item.id} draggableId={item.id} index={index}>
                  {(provided, snapshot) => (
                    <div
                      ref={provided.innerRef}
                      {...provided.draggableProps}
                      {...provided.dragHandleProps}
                      style={{
                        ...provided.draggableProps.style,
                        opacity: snapshot.isDragging ? 0.8 : 1,
                      }}
                    >
                      <List.Item
                        key={item.name}
                        prefix={
                          <Image
                            src={item.avatar}
                            style={{ borderRadius: 24 }}
                            fit='cover'
                            width={48}
                            height={48}
                          />
                        }
                      >
                        {item.name}
                      </List.Item>
                    </div>
                  )}
                </Draggable>
              ))}
              {droppableProvided1.placeholder}
            </div>
          )}
        </Droppable>
      </DragDropContext>
    </List>
  )
}

3.mork数据

 export const users1 = [
    {
      id: '10',
      avatar:
        'https://images.unsplash.com/photo-1548532928-b34e3be62fc6?ixlib=rb-1.2.1&q=80&fm=jpg&crop=faces&fit=crop&h=200&w=200&ixid=eyJhcHBfaWQiOjE3Nzg0fQ',
      name: '1',
    },
    {
      id: '20',
      avatar:
        'https://images.unsplash.com/photo-1493666438817-866a91353ca9?ixlib=rb-0.3.5&q=80&fm=jpg&crop=faces&fit=crop&h=200&w=200&s=b616b2c5b373a80ffc9636ba24f7a4a9',
      name: '2',
    },
    {
      id: '30',
      avatar:
        'https://images.unsplash.com/photo-1542624937-8d1e9f53c1b9?ixlib=rb-1.2.1&q=80&fm=jpg&crop=faces&fit=crop&h=200&w=200&ixid=eyJhcHBfaWQiOjE3Nzg0fQ',
      name: '3',
    },
    {
      id: '40',
      avatar:
        'https://images.unsplash.com/photo-1546967191-fdfb13ed6b1e?ixlib=rb-1.2.1&q=80&fm=jpg&crop=faces&fit=crop&h=200&w=200&ixid=eyJhcHBfaWQiOjE3Nzg0fQ',
      name: '4',
    },
  ]

4、最后肯定是需要实时的保存数据,以上只是构写的demo,没有构写相关逻辑,可调用后端接口在多列表数组传递即可。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容