предисловие
Недавно я писал бэкенд с помощью Ant Design, и столкнулся с требованием реализовать дерево, которое может динамически увеличивать, уменьшать и редактировать дочерние узлы. Я посмотрел на GitHub, и он не был простым в использовании и подходящим. Просто напишите его на основе компонента Tree в Ant Design. Достигаемый эффект следующий:
- можно добавить дочерние узлы
- дочерние узлы могут быть удалены
- Может редактировать информацию о дочернем узле
- Может отменить редактирование информации
Конкретная схема эффекта выглядит следующим образом:
Главное использоватьTreeNode
изtitle
свойство, его типstring|ReactNode
.
текст
После анализа структура данных узла должна быть
{
value: 'Root', // 显示的信息
defaultValue: 'Root', // 当某一节点进入编辑状态,然后点击close按钮,节点的信息应该恢复原始状态,
key: '0-1', // 节点的Key,全局唯一
parentKey: '0', // 父节点的Key
isEditable: false // 是否处于可编辑状态
children:[] // 子节点
}
Сборка через структуры данныхTreeNode
Код выглядит следующим образом:
data= [
{
value: 'Root',
defaultValue: 'Root',
key: '0-1',
parentKey: '0',
isEditable: false
}
];
state={
data: this.data
}
renderTreeNodes = data => data.map((item) => {
if (item.isEditable) { // 编辑状态下
item.title = (
<div>
<input value={item.value}
onChange={(e) => this.onChange(e, item.key)}/>
<Icon type='close' style={{marginLeft:10}} onClick={() => this.onClose(item.key, item.defaultValue)}/>
<Icon type='check' style={{marginLeft:10}} onClick={() => this.onSave(item.key)}/>
</div>
);
} else {
item.title = (
<div>
<span>
{item.value}
</span>
<Icon style={{ marginLeft: 10 }} type='edit' onClick={() => this.onEdit(item.key)} />
<Icon style={{ marginLeft: 10 }} type='plus' onClick={() => this.onAdd(item.key)} />
{item.parentKey === '0' ? null : (<Icon style={{ marginLeft: 10 }} type='minus' onClick={() => this.onDelete(item.key)} />)} // 根节点没有删除按钮
</div>
)
}
if (item.children) {
return (
<TreeNode title={item.title} key={item.key} dataRef={item}>
{this.renderTreeNodes(item.children)}
</TreeNode>
);
}
return <TreeNode {...item}/>;
})
...
// 渲染界面
render() {
return (
<div>
<Tree>
{this.renderTreeNodes(this.state.data)}
</Tree>
</div>
)
}
Все последующие добавления, удаления, модификации и т. д. изменяются в первую очередьdata
данные в этом массиве, а затем используйтеthis.setState({ data: this.data })
Обновите интерфейс, просто посмотрите на код, это очень просто.
При окончательной оптимизации этого компонента я столкнулся с ямой. Первоначально считалось, что когда дочерний узел добавляется к узлу, родительский узел автоматически расширяется, и нет проблем с логикой кода, но логика должна выполняться вручную один раз, чтобы расширить или найти написанную логику, чтобы она вступила в силу. Позже другого пути нет, но его можно активировать только после загрузки DOM в функции жизненного цикла:
componentDidMount() {
this.onExpand([]); // 手动触发,否则会遇到第一次添加子节点不展开的Bug
}
Код находится на GitHub по адресуreact-editable-tree, Добро пожаловать в ссылку небольших партнеров, которые имеют такие же потребности,star
а такжеfork
Тоже отлично.