树形结构目录,可编辑,可新增

树形结构目录,可编辑,可新增

新增状态
编辑状态
hover状态

// An highlighted block
import React, { Component } from "react";
import { Tree, Icon } from "antd";
import styles from "./EditableTree.less";
const { TreeNode } = Tree;

class EditableTree extends Component {
  data = [
    {
      value: "1",
      defaultValue: "1",
      key: "0-1",
      parentKey: "0",
      isEditable: false,
      children: [
        {
          value: "1-1",
          defaultValue: "1-1",
          key: "0-1-1",
          parentKey: "0-1",
          isEditable: false,
        },
        {
          value: "1-2",
          defaultValue: "1-2",
          key: "0-1-2",
          parentKey: "0-1",
          isEditable: false,
        },
      ],
    },
    {
      value: "2",
      defaultValue: "2",
      key: "0-2",
      parentKey: "0",
      isEditable: false,
      children: [
        {
          value: "2-1",
          defaultValue: "2-1",
          key: "0-1-3",
          parentKey: "0-1",
          isEditable: false,
        },
      ],
    },
  ];
  expandedKeys = [];

  state = {
    expandedKeys: [],
    data: this.data,
  };

  componentDidMount() {
    this.onExpand(["0-1", "0-2", "0-3"]); // 默认展开
  }

  onExpand = (expandedKeys) => {
    this.expandedKeys = expandedKeys;
    this.setState({ expandedKeys: expandedKeys });
  };

  renderTreeNodes = (data) =>
    data.map((item) => {
      if (item.isEditable) {//编辑状态下为input
        item.title = (
          <div>
            <input
              className={styles.inputField}
              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 className={styles.titleContainer}>
            <span className={styles.operationSpan}>{item.value}</span>
            <span className={styles.operationField}>
              {item.parentKey == 0 ? ( //根标签不可编辑
                ""
              ) : (
                <Icon
                  style={{ marginLeft: 10 }}
                  type="edit"
                  onClick={() => this.onEdit(item.key)}
                />
              )}
              {item.parentKey == 0 ? ( //只有根标签才可以新增
                <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)}
                />
              )}
            </span>
          </div>
        );
      }
      //递归
      if (item.children) {
        return (
          <TreeNode title={item.title} key={item.key} dataRef={item}>
            {this.renderTreeNodes(item.children)}
          </TreeNode>
        );
      }

      return <TreeNode {...item} />;
    });

//新增
  onAdd = (e) => {
    // 防止expandedKeys重复
    if (this.state.expandedKeys.indexOf(e) === -1) {
      this.expandedKeys.push(e);
    }
    this.addNode(e, this.data);
    this.setState({
      expandedKeys: this.expandedKeys,
      data: this.data,
    });
  };

  addNode = (key, data) =>
    data.map((item) => {
      if (item.key === key) {
        if (item.children) {
          item.children.push({
            value: "default",
            defaultValue: "default",
            key: key + Math.random(100), //唯一的key
            parentKey: key,
            isEditable: false,
          });
        } else {
          item.children = [];
          item.children.push({
            value: "default",
            defaultValue: "default",
            key: key + Math.random(100),
            parentKey: key,
            isEditable: false,
          });
        }
        return;
      }
      if (item.children) {
        console.log(item.children, "item.children)");
        this.addNode(key, item.children);
      }
    });
//删除
  onDelete = (key) => {
    console.log("delete");
    this.deleteNode(key, this.data);
    this.setState({
      data: this.data,
    });
  };

  deleteNode = (key, data) =>
    data.map((item, index) => {
      if (item.key === key) {
        data.splice(index, 1);
        return;
      } else {
        if (item.children) {
          this.deleteNode(key, item.children);
        }
      }
    });

//编辑
  onEdit = (key) => {
    console.log("edit");
    this.editNode(key, this.data);
    this.setState({
      data: this.data,
    });
  };

  editNode = (key, data) =>
    data.map((item) => {
      if (item.key === key) {
        item.isEditable = true;
      } else {
        item.isEditable = false;
      }
      item.value = item.defaultValue; // 当某节点处于编辑状态,并改变数据,点击编辑其他节点时,此节点变成不可编辑状态,value 需要回退到 defaultvalue
      if (item.children) {
        this.editNode(key, item.children);
      }
    });
//关闭编辑
  onClose = (key, defaultValue) => {
    console.log("close");
    this.closeNode(key, defaultValue, this.data);
    this.setState({
      data: this.data,
    });
  };

  closeNode = (key, defaultValue, data) =>
    data.map((item) => {
      item.isEditable = false;
      if (item.key === key) {
        item.value = defaultValue;
      }
      if (item.children) {
        this.closeNode(key, defaultValue, item.children);
      }
    });
//保存编辑内容
  onSave = (key) => {
    console.log("save");
    this.saveNode(key, this.data);
    this.setState({
      data: this.data,
    });
  };

  saveNode = (key, data) =>
    data.map((item) => {
      if (item.key === key) {
        item.defaultValue = item.value;
      }
      if (item.children) {
        this.saveNode(key, item.children);
      }
      item.isEditable = false;
    });

  onChange = (e, key) => {
    console.log("onchange");
    this.changeNode(key, e.target.value, this.data);
    this.setState({
      data: this.data,
    });
  };

  changeNode = (key, value, data) =>
    data.map((item) => {
      if (item.key === key) {
        item.value = value;
      }
      if (item.children) {
        this.changeNode(key, value, item.children);
      }
    });

  render() {
    return (
      <div className={styles.TreeNode}>
        <Tree
          expandedKeys={this.state.expandedKeys}
          selectedKeys={[]}
          onExpand={this.onExpand}
        >
          {this.renderTreeNodes(this.state.data)}
        </Tree>
      </div>
    );
  }
}

export default EditableTree;

// css部分
.TreeNode{
width:330px;
height:700px;
overflow-y: auto;
margin-right: 10px;
margin-top: 55px;
    .inputField {
        border: none;
        border: 1px solid;
        background: none;
        border-radius: 2px;
        line-height: normal;
        min-width: 50px;
        outline: none;
        &:focus {
            outline: none;
        }
    }
    
    .titleContainer {
        .operationField {
            visibility: hidden;
        }
    
        &:hover {
            .operationField {
                visibility: visible;
                color:blue
            };
            .operationSpan{
                color:blue
            }
        }
    }
    
}
:global {
    .ant-tree li .ant-tree-node-content-wrapper:hover {
        background-color: unset;
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值