Antd Tree,实现排序拖动,父子层级内外拖动

拖动属性dropToGap,dropPosition

属性解释:

dropToGap:
boolean类型,true代表拖拽到节点之间的缝隙中,false代表拖拽到节点上,即节点的内容区。

dropPosition:
拖拽的时候,针对一个节点有三种情况,即拖拽到节点之上,拖拽到节点上,拖拽到节点之下。
三种情况其值有所不同。antd 依赖了 rc-tree,在 rc-tree 里 dropPosition 是一个相对地址。
如果拖到了目标节点的上面则当前元素 -1,下面则是 1(* rc-tree这块不确定具体情况*)。

antd 里则是相对于目标节点的 index针对拖动情况计算出来。
拖拽到节点之上: 该节点的 index-1
拖拽到节点上:dropPosition 就是该节点的 index。
拖拽到节点之下:该节点的 index+1

image

官方案例

 onDrop = info => {
    console.log(info);
    const dropKey = info.node.props.eventKey;
    const dragKey = info.dragNode.props.eventKey;
    const dropPos = info.node.props.pos.split('-');
   // 这里计算的差值 上面分析了info.dropPosition的含义   dropPosition有3种情况 
   // =0 表示拖拽到元素上
  // =1 表示拖拽到元素下面   那么放置元素的时候  应该放到这个位置+1的位置上
  // =-1 表示拖拽到元素上面   那么放置元素的时候 直接放到这个位置即可
    const dropPosition = info.dropPosition - Number(dropPos[dropPos.length - 1]);

// 递归查到元素所在树中的位置
    const loop = (data, key, callback) => {
      data.forEach((item, index, arr) => {
        if (item.key === key) {
          //在回调函数中将此元素,位置,以及元数组都返回
          return callback(item, index, arr);
        }
        if (item.children) {
          return loop(item.children, key, callback);
        }
      });
    };
    // 浅拷贝整个树 此处有疑问  不过不影响功能  因为怕操作data 我觉得应该深拷贝 
    const data = [...this.state.gData];

    // Find dragObject 查找获取到拖拽开始的元素对象
    let dragObj;
    loop(data, dragKey, (item, index, arr) => {
      // 查找到后删除此元素  这里相当于直接操作了data 所以我认为应该深拷贝
      arr.splice(index, 1);
      dragObj = item;
    });

    if (!info.dropToGap) {
      // Drop on the content  拖拽到内容上 
      loop(data, dropKey, item => {
        item.children = item.children || [];
        // where to insert 示例添加到尾部,可以是随意位置
        item.children.push(dragObj);
      });
    }
    // 拖拽到元素之下的缝隙中,元素有子节点,并且当前元素子节点展开。此时元素放到了子节点的第一位。(当然可以根据具体情况随意位置) 
    else if (
      (info.node.props.children || []).length > 0 && // Has children
      info.node.props.expanded && // Is expanded
      dropPosition === 1 // On the bottom gap
    ) {
      loop(data, dropKey, item => {
        item.children = item.children || [];
        // where to insert 示例添加到头部,可以是随意位置
        item.children.unshift(dragObj);
      });
    } else {
      let ar;
      let i;
      loop(data, dropKey, (item, index, arr) => {
        ar = arr;
        i = index;
      });
      if (dropPosition === -1) {
        ar.splice(i, 0, dragObj);
      } else {
        ar.splice(i + 1, 0, dragObj);
      }
    }

    this.setState({
      gData: data,
    });
  };
posted @ 2022-09-22 10:54  Tommy_marc  阅读(1359)  评论(0编辑  收藏  举报