作为一手angular的小菜鸟,为了追求技术(工资)不得不学习React。
不得不说,react作为使用JSX语法的框架,用来写树组件还是十分有优势的。
1.渲染出树组件
constructor(props) {
super(props);
this.state = {
arr: [
{
id: 0,
value: "root",
children: [],
parent: null,
date: 0,
collapsed: "icon-zhedie2"
}
],
currentId: 1
};
this.setDateInterval();
}
render() {
return (
<ul>{this.state.arr.length > 0 && this.renderNode(this.state.arr)}</ul>
);
}
/**
* 渲染节点
*/
renderNode(data) {
return data.map((item) => {
return (
<li key={item.id}>
<div
className={`iconfont ${item.collapsed}`}
onClick={() => this.collapsedHandler(item)}
></div>
<div
className="value"
contentEditable="true"
suppressContentEditableWarning="true"
>
{item.value}
</div>
<div
onClick={() => this.createNodeHanlder(item)}
className="iconfont icon-zhedie"
></div>
<div
onClick={() => this.delNodeHanlder(item)}
className="iconfont icon-zhedie1"
></div>
<div className="passed-time">passed {item.date}'</div>
<ul>{item.children ? this.renderNode(item.children) : ""}</ul>
</li>
);
});
}
2.功能函数
/**
* 点击创建子节点
*/
createNodeHanlder(item) {
item.children.push({
id: this.state.currentId,
value: "value",
children: [],
parent: item,
collapsed: "",
date: 0
});
item.collapsed = "icon-zhedie2";
this.setState({
arr: [...this.state.arr],
currentId: this.state.currentId + 1
});
}
/**
* 删除子节点
*/
delNodeHanlder(item) {
if (!item.parent) {
return;
}
const index = item.parent.children.findIndex((fele) => fele === item);
item.parent.children.splice(index, 1);
this.setState({
arr: [...this.state.arr]
});
}
/**
* 折叠
*/
collapsedHandler(item) {
if (item.collapsed === "icon-zhedie2") {
item.collapsed = "icon-close collapsed";
this.setState({
arr: [...this.state.arr]
});
} else if (item.collapsed === "icon-close collapsed") {
item.collapsed = "icon-zhedie2";
this.setState({
arr: [...this.state.arr]
});
}
}
/**
* 建立计时器
*/
setDateInterval() {
const that = this;
setInterval(() => {
that.queryAllNode(that.state.arr);
}, 1000);
}
/**
* 遍历所有节点,并为所有date+1秒
*/
queryAllNode(data) {
return data.map((item) => {
if (item.children && item.children.length !== 0) {
item.date++;
this.setState({
arr: [...this.state.arr]
});
this.queryAllNode(item.children);
} else {
item.date++;
this.setState({
arr: [...this.state.arr]
});
}
return item;
});
}
3.样式
ul li {
list-style: none;
padding: 0px;
margin: 0px;
}
div {
display: inline-block;
}
.value {
margin-right: 5px;
}
.value:hover ~ .passed-time {
display: inline;
color: #0fd59d;
}
.iconfont:hover {
color: #0fd59d;
}
div.collapsed ~ ul {
display: none;
}
.passed-time {
margin-left: 5px;
display: none;
color: #0fd59d;
}
在线浏览:https://codesandbox.io/s/react-training-forked-tdnts?file=/src/index.js
4.总结
1.主要是熟悉树结构的遍历
2.熟悉react框架的渲染、数据绑定、事件绑定。