以下是这个组件中需要实现的功能
- 树的节点拖拽并且只能是平级与平级之间
- 节点hover出现新增删除编辑设置
引入树组件
import { Tree } from 'antd';
const { TreeNode } = Tree;
构造树的假数据
this.state = {
treeData: [{
title: '获奖行为',
key: '获奖行为',
children: [{
title: '奥赛',
key: '奥赛'
}, {
title: '运动会',
key: '运动会'
}]
}, {
title: '学习行为',
key: '学习行为',
children: [{
title: '下乡',
key: '下乡'
}]
}],
nodeId: '',
nodeName: '',
selectedKeys: []
}
render 树组件
{this.loop(this.state.treeData, '')}
递归树节点 loop方法
title类型为string|ReactNode
由于需要hover显示出设置所以在title里直接写
loop(data, parentId) {
return data.map(item => {
if (item.children && item.children.length) {
return (
{item.title}
设置
}>
{this.loop(item.children, item.key)}
);
}
return
{item.title}
设置
} />;
});
}
拖拽时
onDrop(info) {
const dropKey = info.node.props.eventKey; //拖拽落下的值
const dragKey = info.dragNode.props.eventKey; //被拖拽的值
const dropPos = info.node.props.pos.split('-'); //拖拽落下的位置 最外层到最里层
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);
}
});
};
const data = [...this.state.treeData];
// Find dragObject
let dragObj;
let drag = info.dragNode.props.pos;
let dragLength = info.dragNode.props.pos.split('-').length;
let drop = info.node.props.pos;
let dropLength = info.node.props.pos.split('-').length;
if (!info.dropToGap) {
//平级与平级之间不能拖拽为子级
if((dropPosition==0&&dropPos.length==3)||(dropPosition==0&&dropPos.length==2&&dragLength==2)){
}else{
loop(data, dragKey, (item, index, arr) => {
arr.splice(index, 1);
dragObj = item;
});
loop(data, dropKey, item => {
item.children = item.children || [];
// where to insert 示例添加到尾部,可以是随意位置
item.children.push(dragObj);
});
}
// Drop on the content
} else if (
(info.node.props.children || []).length > 0 && // Has children
info.node.props.expanded && // Is expanded
dropPosition === 1 // On the bottom gap
) {
loop(data, dragKey, (item, index, arr) => {
arr.splice(index, 1);
dragObj = item;
});
loop(data, dropKey, item => {
item.children = item.children || [];
// where to insert 示例添加到头部,可以是随意位置
item.children.unshift(dragObj);
});
}
else {
//一级不能拖拽为二级、二级子级
if((dragLength==3&&dropLength==2)||(dragLength==2&&dropLength==3)){
return;
}
loop(data, dragKey, (item, index, arr) => {
arr.splice(index, 1);
dragObj = item;
});
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({
treeData: data,
});
}
判断length是否等于2或者是等于3,是因为树节点生成时默认一级为0-0,二级为0-0-0,split后length就是2或者3了。
目前项目中树只有两级所以采取这种曲线救国的方式,空了再研究适用于所有级的平级拖拽。