记录antd的Tree型控件拖拽细节

2,600 阅读3分钟

本文旨在对Antd拖拽树中的几个重要参数进行验证讨论,以便在开发时可以增加对其拖拽的限制。 生成如下数据

[{
    nav_id: 1,
    key: 1,
    nav_name: '分组一',
    children: [
        { nav_id: 11, nav_name: '11', key: 11 },
        { nav_id: 12, nav_name: '12', key: 12 }]
},
{
    nav_id: 2,
    key: 2,
    nav_name: '分组二',
    children: [
        { nav_id: 21, nav_name: '21', key: 21 },
        { nav_id: 22, nav_name: '22', key: 22 }
    ]
},
{
    id: 3,
    nav_name: '分组三',
    key: 3,
    children: [
        { nav_id: 31, nav_name: '31', key: 31 },
        { nav_id: 32, nav_name: '32', key: 32 },
        { nav_id: 33, nav_name: '33', key: 33 },
        { nav_id: 34, nav_name: '34', key: 34 }
    ]
}
]

其渲染结果如下

image.png

在antd官网的Tree型组件拖动的示例中,提供了一个onDrop方法,用来实现拖拽功能,onDrop方法的参数是一个info对象,如下是官网示例中的一段。定义了四个变量,下面对这四个变量进行详细的说明

const dropKey = info.node.key; 
const dragKey = info.dragNode.key; 
const dropPos = info.node.pos.split('-'); 
const dropPosition = info.dropPosition - Number(dropPos[dropPos.length - 1]);

info对象

info对象是onDrop方法的参数,主要提供了拖拽的相关信息

  • info.node是落下的节点信息
  • info.dragNode是拖拽的节点信息
  • info.dropPosition是落下的位置信息

image.png

dropKey

dropKey是拖拽后所落在的节点key,选取放置位置的上一个元素(同级或上级),当最顶的时候是下一个元素

  • 将节点31拖到节点32下边(平级或下级),那么dropKey就是32
  • 将节点32拖到31上边,它会判定dropKey为3,因为31上边没有平级元素,所以找到了父级元素3
  • 将节点3拖到节点1前边,dropKey为1,节点1上边没有父级和平级(最顶),所以取下边的元素

dragKey

拖拽的节点key,拖动哪个节点,dragKey就是那个节点的key

dropPos

dropPos是通过info.node.pos转换而来的

 const dropPos = info.node.pos.split('-')
  • pos这个是tree生成的属性,用来标识节点的所在层级
  • 例如节点31, 用{pos:"0-2-0"}表示,第一个0可以看成是默认的,2-0,分别表示每个层级的下标
  • 最后一个0,表示叶子节点(最后一级)的下标

dropPosition

dropPosition也是由其他变量转换而来

const dropPosition = info.dropPosition - Number(dropPos[dropPos.length - 1]);

我们用index来表示叶子节点的下标,即

const index = Number(dropPos[dropPos.length - 1])

我们先来看看info.dropPosition的生成逻辑,info.dropPosition会根据dropKey的index算出不同的值,平级在下为index+1,平级在上为index-1,子级为index

  • 如果我们将节点34拖到31下面,那么dropKey是31,index是0,平级在下展示,info.dropPosition=index+1=1;
  • 如果我们将节点34拖到31上面,此时的dropKey会是3(详见dropKey的生成规则),index=2,相当于变成了3的子级,info.dropPosition=index=2;
  • 如果我们将节点34拖到33上面,此时的dropKey会是32(详见dropKey的生成规则),index=1,平级在上展示,info.dropPosition=index-1=0
  • 如果我们将节点3拖到1上面,1是最顶的元素,那么dropKey是1,index=0,平级在上显示,info.dropPosition=index-1=-1

所以dropPosition这个变量其实是在计算拖拽后节点与dropKey的位置关系( 即info.dropPosition-index)

  1. dropPosition = -1,是移动到和dropKey的平级,并在其上面(即info.dropPosition比dropKey的下标小一个)。
  2. dropPosition = 1,是移动到和dropKey的平级,并在其下面(info.dropPosition比dropKey的下标大一个)。
  3. dropPosition = 0,是移动到dropKey下面作为他的子级(info.dropPosition和dropKey的下标同样大)。