手写一个React树组件(Tree)

作为一手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框架的渲染、数据绑定、事件绑定。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值