zoukankan      html  css  js  c++  java
  • react拖拽案例

    自己随手写了一个小案例,记录一下。

    1、实现右边盒子内容拖到左边盒子里。

    依赖 -- -- 

    react-dnd 
    react-dnd-html5-backend
     
    2、实现左边盒子资源的拖动
    依赖 -- -- 
    react-beautiful-dnd
     
    (1) ---- index.js
    import React, { Component } from "react";
    import { DndProvider } from 'react-dnd'
    import { HTML5Backend } from 'react-dnd-html5-backend'
    import Dustbin from "./Dustbin";
    import Box from "./Box";
    import "./index.less";
    
    class Home extends Component {
      state = {
        mainList: [
          {id: 'item-6', content: 'aaaaaaaaa'},
          {id: 'item-7', content: 'bbbbbbbbb'},
          {id: 'item-8', content: 'ccccccccc'},
          {id: 'item-9', content: 'ddddddddd'},
          {id: 'item-10', content: 'eeeeeeeee'},
          {id: 'item-11', content: 'fffffffff'},
        ],
        sideList: [
          { id: "item-0", content: "hello" },
          { id: "item-1", content: "I" },
          { id: "item-2", content: "am" },
          { id: "item-3", content: "卡" },
          { id: "item-4", content: "特" },
          { id: "item-5", content: "洛" },
        ]
      }
    
      endPull = (opt) => {
        const sideList = [...this.state.sideList, opt];
        // alert('添加成功')
        this.setState({ sideList })
      }
    
      reOrder = (list, startIndex, endIndex) => {
        const result = Array.from(list);
        const [removed] = result.splice(startIndex, 1);
        result.splice(endIndex, 0, removed);
        return result;
      };
    
      onDragEnd = (result) => {
        console.log(result)
        if (!result.destination) return;
    
        const sideList = this.reOrder(
          this.state.sideList,
          result.source.index,
          result.destination.index
        );
        this.setState({ sideList })
      };
    
      render() {
        return (
          <div style={{ paddingLeft: 200, paddingTop: 50, display: 'flex' }} className='page-home'>
           <DndProvider backend={HTML5Backend}>
            <div>
              <Dustbin sideList={this.state.sideList} switchSeat= {sideList => this.setState({ sideList })} />
            </div>
    
            <div style={{flex: 1, display: 'flex', flexWrap: 'wrap'}}>
              {/* 案例实现的是循环里数据都能实现拖拽,所以要循环组件 */}
              {
                this.state.mainList.map(item => {
                  return (
                    <Box
                      key={item.id} 
                      item={item}
                      endPull={this.endPull}
                    />
                  )
                })
              }
            </div>
           </DndProvider>
          </div>
        );
      }
    }
    
    export default Home
    

      

    (2) -- -- Box.index

    import React from "react";
    import { DragSource } from "react-dnd";
    let endPull = null;
    
    const boxSource = {
      /**
       * 开始拖拽时触发当前函数
       * @param {*} props 组件的 props
       */
      beginDrag(props) {
        // 返回的对象可以在 monitor.getItem() 中获取到
        return {
          // name: props.name,
        };
      },
    
      /**
       * 拖拽结束时触发当前函数
       * @param {*} props 当前组件的 props
       * @param {*} monitor DragSourceMonitor 对象
       */
      endDrag(props, monitor) {
        // 当前拖拽的 item 组件
        // const item = monitor.getItem();
        // 拖拽元素放下时,drop 结果
        const dropResult = monitor.getDropResult();
        // 如果 drop 结果存在,就弹出 alert 提示
        if (dropResult) {
          // alert(`You dropped ${item.name} into ${dropResult.name}!`);
          if(!endPull) return;
          endPull(props.item);
        }
      },
    };
    
    @DragSource(
      // type 标识,这里是字符串 'box'
      // ItemTypes.BOX,
      'box',
      // 拖拽事件对象
      boxSource,
      // 收集功能函数,包含 connect 和 monitor 参数
      // connect 里面的函数用来将 DOM 节点与 react-dnd 的 backend 建立联系
      (connect, monitor) => ({
        // 包裹住 DOM 节点,使其可以进行拖拽操作
        connectDragSource: connect.dragSource(),
        // 是否处于拖拽状态
        isDragging: monitor.isDragging(),
      })
    )
    
    class Box extends React.Component {
      componentDidMount() {
        endPull = this.props.endPull;
      }
    
      render() {
        const { connectDragSource } = this.props;
        const { item } = this.props;
        // 使用 connectDragSource 包裹住 DOM 节点,使其可以接受各种拖动 API, connectDragSource 包裹住的 DOM 节点才可以被拖动
    
        return (
          <div style={{display: 'flex'}}>
            {
              connectDragSource &&
              connectDragSource(
                <div key={item.key} style={{ '200px', margin: '50px'}}>
                  <dl style={{ '200px', height: '100px'}}>
                    <dt style={{height: '70px', background: 'pink'}}>图片</dt>
                    <dd style={{height: '30px', background: '#eee'}}>{item.content}</dd>
                  </dl>
                </div>
              )
            }
          </div>
        );
      }
    }
    
    export default Box;
    

      

    (3) -- -- Dustbin.js

    import React from "react";
    import { DropTarget } from "react-dnd";
    import { Collapse } from "antd";
    import { DragDropContext, Droppable, Draggable } from "react-beautiful-dnd";
    
    const { Panel } = Collapse;
    
    const boxTarget = {
      // 当有对应的 drag source 放在当前组件区域时,会返回一个对象,可以在 monitor.getDropResult() 中获取到
      drop: () => ({ name: "Dustbin" }),
    };
    
    @DropTarget(
      // type 标识,这里是字符串 'box'
      // ItemTypes.BOX,
      "box",
      // 接收拖拽的事件对象
      boxTarget,
      // 收集功能函数,包含 connect 和 monitor 参数
      // connect 里面的函数用来将 DOM 节点与 react-dnd 的 backend 建立联系
      (connect, monitor) => ({
        // 包裹住 DOM 节点,使其可以接收对应的拖拽组件
        connectDropTarget: connect.dropTarget(),
        // drag source是否在 drop target 区域
        isOver: monitor.isOver(),
        // 是否可以被放置
        canDrop: monitor.canDrop(),
      })
    )
    class Dustbin extends React.Component {
      state = {
        keyActive: "1",
        periodList: [
          { id: 1, name: "测试1" },
          { id: 2, name: "测试2" },
          { id: 3, name: "测试3" },
        ],
      };
    
      onCollapseChange = (key) => {
        if (key) {
          this.setState({ keyActive: key });
        }
      };
    
      reOrder = (list, startIndex, endIndex) => {
        const result = Array.from(list);
        const [removed] = result.splice(startIndex, 1);
        result.splice(endIndex, 0, removed);
        return result;
      };
    
      onDragEnd = (result) => {
        console.log(result);
        if (!result.destination) return;
    
        const sideList = this.reOrder(
          this.props.sideList,
          result.source.index,
          result.destination.index
        );
    
        this.props.switchSeat(sideList);
      };
    
      render() {
        const { connectDropTarget } = this.props;
        const { sideList } = this.props;
        const { keyActive, periodList } = this.state;
    
        return (
          <div
            style={{  "200px", border: "1px solid gray", height: "500px" }}
          >
            <Collapse
              accordion
              ghost
              className="collapse_wrap"
              // activeKey={1}
              activeKey={keyActive}
              onChange={this.onCollapseChange}
            >
              {periodList &&
                periodList.map((item, index) => {
                  return (
                    <Panel header={item.name} key={item.id} showArrow={false}>
                      <React.Fragment>
                        {connectDropTarget &&
                          connectDropTarget(
                            <div>
                              <DragDropContext
                                onDragEnd={this.onDragEnd}
                              >
                                <Droppable droppableId="droppable">
                                  {(provided) => (
                                    <div
                                      ref={provided.innerRef}
                                      {...provided.droppableProps}
                                    >
                                      {sideList.map((item, index) => (
                                        <Draggable
                                          // 这个key值必须是string类型, 不能是number, 想知道为什么,自己试下就知道了。
                                          key={item.id}
                                          draggableId={item.id}
                                          index={index}
                                        >
                                          {(provided) => (
                                            <div
                                              ref={provided.innerRef}
                                              {...provided.draggableProps}
                                              {...provided.dragHandleProps}
                                            >
                                              <span
                                                style={{
                                                  display: "block",
                                                  height: "30px",
                                                  lineHeight: "30px",
                                                  borderBottom: "1px solid red",
                                                  paddingLeft: "10px",
                                                }}
                                              >
                                                {item.content}
                                              </span>
                                            </div>
                                          )}
                                        </Draggable>
                                      ))}
                                      {provided.placeholder}
                                    </div>
                                  )}
                                </Droppable>
                              </DragDropContext>
                            </div>
                          )}
                      </React.Fragment>
    
                      {/* {
                        connectDropTarget &&
                        connectDropTarget(
                          <div className='class_hour_list'>
                            {
                              detailList.map(v => {
                                return (
                                  <p key={v}>{v.name}</p>
                                )
                              })
                            }
                          </div>
                        )
                      } */}
                    </Panel>
                  );
                })}
            </Collapse>
          </div>
        );
      }
    }
    
    export default Dustbin;
    

      

  • 相关阅读:
    并发量,tps,qps
    MYSQL安装和配置
    python 生成随机数的几种方法
    python 判断是字母的多种方法
    python实战,
    linux工作常用命令
    apache http server安装
    .py与.pyc文件区别
    上传本地文件到linux
    ms
  • 原文地址:https://www.cnblogs.com/yetiezhu/p/14807623.html
Copyright © 2011-2022 走看看