<>背景
最近公司所做的项目中有个文档管理的需求,需要有个目录来展示不同的文档。可以对文档目录进行添加、重命名、删除、切换等操作。但是antd的tree组件不能完全满足需要,于是就进行了二次封装。
先看看效果图:
<>难点
主要的难点是这个hover按钮,之前没什么思路。后来想一想,可以放在数据中的title里面,antd中的数据都可以将一段jsx放进去。如下:
const TreeTitle = (props) => { const { title, id } = props; return (
<React.Fragment> <span>{title}</span> {id === 'root' ? null : ( <Popover
content={<PopoverContent id={id} title={title} />} placement="rightTop" >
<MoreOutlined className="icon-operate" /> </Popover> )} </React.Fragment> ); };
这里的root要注意一下,上面的效果图中的所有类别的id就是root,这是我手动添加到类别数组中的,不是后端返回的,所以不需要hover图标,才加了上面这一层处理。
然后用了递归生成目录树所需的数据结构,如下:
// 加工后端返回的treedata,给title加上hover显示图标 const gernerateTreeData = (data) => {
data = data.map((item) => { if (item.children && item.children.length) { return
{ key: item.key, title: <TreeTitle title={item.title} id={item.key} />,
children: gernerateTreeData(item.children), }; } else { return { key: item.key,
title: <TreeTitle title={item.title} id={item.key} />, }; } }); return data; };
html部分就比较简单,如下:
<div style={{ height: '100%', paddingTop: '20px' }}> <Row
justify="space-between"> <Input prefix={<SearchOutlined style={{ color: '#ddd'
}} />} style={{ marginLeft: '10px', marginBottom: '10px', width: '120px' }}
size="small" allowClear onChange={this.handleSearch} /> <Button style={{
marginRight: '5px' }} size="small" onClick={() => this.showAddConfirm('add')}
disabled={this.state.isEditing} > <PlusOutlined /> </Button> </Row>
{this.state.treeData.length ? ( <DirectoryTree style={{ marginLeft: '8px' }}
treeData={gernerateTreeData(this.state.treeData)} showIcon={false}
expandedKeys={this.state.expandedKeys} onExpand={this.expand}
switcherIcon={<DownOutlined />} onSelect={this.select} ></DirectoryTree> ) :
null} </div>
最终效果还是不错的,达到了业务的要求。完美! 洗洗睡。