效果如图
可以拖拽,修改新增和删除
代码
import React, { useState, useEffect } from 'react';
import { Modal, Button, Form, Input, Select, Checkbox, Divider, Tree, Message } from 'antd';
import { PlusOutlined, CloseOutlined,DeleteOutlined,PlusCircleOutlined } from '@ant-design/icons';
import style from './style.less';
const { TreeNode } = Tree;
var tempKey = '1';
const { DirectoryTree } = Tree;
const App = (props) => {
var treeDataTemp = [
{
title: '资源结构树',
key: '-1',
children: [
/* {
title: '0-0-0',
key: '0-0-0',
children: [
{
title: '0-0-0-0',
key: '0-0-0-0'
},
{
title: '0-0-0-1',
key: '0-0-0-1'
}
]
},
{
title: '0-0-2',
key: '0-0-2'
} */
]
},
/* {
title: '0-2',
key: '0-2'
} */
];
const [treeData, setTreeData] = useState(treeDataTemp);
const onDragEnter = (info) => {
console.log(info);
};
const onDrop = (info) => {
console.log(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]);
const loop = (data, key, callback) => {
for (let i = 0; i < data.length; i++) {
if (data[i].key === key) {
return callback(data[i], i, data);
}
if (data[i].children) {
loop(data[i].children, key, callback);
}
}
};
const data = [...treeData];
// Find dragObject
let dragObj;
loop(data, dragKey, (item, index, arr) => {
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.unshift(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);
// in previous version, we use item.children.push(dragObj) to insert the
// item to the tail of the children
});
} 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);
}
}
setTreeData([...data]);
console.log('data2', data);
};
const onAdd = (key) => {
console.log('onAdd', key);
var treeDataOld = JSON.parse(JSON.stringify(treeData));
var treeDataNew = addNode(key, treeDataOld);
setTreeData(treeDataNew);
tempKey++;
function addNode(key, data) {
data.forEach((item) => {
if (item.key === key) {
item.children
? item.children.push({
title: `新增结构${tempKey}`,
key: `${tempKey}`
})
: (item.children = [
{
title: `新增结构${tempKey}`,
key: `${tempKey}`
}
]);
} else {
if (item.children) {
addNode(key, item.children);
}
}
});
return data;
}
};
const onDelete = (key) => {
console.log('onAdd', key);
var treeDataOld = JSON.parse(JSON.stringify(treeData));
var treeDataNew = deleteNode(key, treeDataOld);
setTreeData(treeDataNew);
function deleteNode(key, arr) {
arr.map((item, index) => {
if (item.key == key) {
arr.splice(index, 1);
}
if (item.children) {
deleteNode(key, item.children);
}
});
return arr;
}
};
const onChange = (e, key) => {
console.log('onChange', e, key);
var treeDataOld = JSON.parse(JSON.stringify(treeData));
var treeDataNew = editNode(key, treeDataOld, e.target.value);
setTreeData(treeDataNew);
function editNode(key, data, val) {
data.forEach((item) => {
if (item.key === key) {
item.title = val;
} else {
if (item.children) {
editNode(key, item.children, val);
}
}
});
return data;
}
};
const renderTreeNodes = (data) => {
console.log('renderTreeNodes', data);
return data.map((item) => {
if (item.children) {
return (
<TreeNode title={item.title} key={item.key}>
{renderTreeNodes(item.children)}
</TreeNode>
);
}
return <TreeNode {...item}></TreeNode>;
});
};
const onTitleRender = (item) => {
return (
<div style={{ display: 'flex', alignItems: 'center'}}>
<Input
// value={item.title}
defaultValue={item.title}
onChange={(e) => onChange(e, item.key)}
/>
<span style={{ display: 'flex',width:'90px' }}>
<PlusCircleOutlined style={{ marginLeft: 40,color:'#6451CB',fontSize:'16px' }} onClick={() => onAdd(item.key)} />
<DeleteOutlined style={{color:'#6451CB',marginLeft: 10,fontSize:'16px',visibility:Number(item.key)<=0?'hidden':"visible"}} onClick={() => onDelete(item.key)} />
</span>
</div>
);
};
return (
<div style={{width:'100%',marginTop:'20px'}} className={style.draggable_tree}>
<DirectoryTree
defaultExpandAll={true}
draggable
//onDragEnter={onDragEnter}
//onDrop={onDrop}
titleRender={onTitleRender}
showIcon={false}
showLine={{showLeafIcon:false}}
treeData={treeData}
expandAction={false}
/>
<div style={{
display: "flex",
justifyContent: "center",
marginTop: "13px",
}}>
<Button type="primary" onClick={() => {
console.log(treeData)
}} >提交</Button>
</div>
</div>
);
};
export default App;
样式
.draggable_tree {
:global {
.ant-tree .ant-tree-treenode {
width: 100%;
}
.ant-tree .ant-tree-node-content-wrapper {
width: 100%;
height: 56px;
padding-top: 12px;
}
.ant-tree-switcher {
line-height: 56px;
}
.ant-tree-node-content-wrapper .ant-tree-node-content-wrapper-close .draggable {
width: 100%;
height: 56px;
padding-top: 12px;
}
/* .ant-input{
width: 300px;
}
.ant-tree-title {
width: 100%;
} */
}
}