HDD、 2021-09-29 14:58 采纳率: 85.7%
浏览 225
已结题

react 树形控件增删改查版本问题,如何解决 Tree的“children”已弃用。 请使用“treeData”。 代码如下

这是树形图片

img


代码参考@赐你岁月如歌,链接:
以下是代码


import styled from "@emotion/styled";
import React, { useState } from "react";
import CommonModal from "@/components/CommonModal";

import { Tree, Button } from "antd";
import {
  EditOutlined,
  PlusOutlined,
  MinusOutlined,
  CloseOutlined,
  CheckOutlined,
  DownCircleOutlined,
} from "@ant-design/icons";

import { nanoid } from "nanoid";

// interface DataNode {
//   title: string;
//   key: string;
//   isLeaf?: boolean;
//   children?: DataNode[];
//   icon: any;
// }
const Doctree = styled(Tree)`
  .ant-tree-list-holder {
    min-height: 800px;
  }
  .ant-tree-list-scrollbar {
    background-color: #004c87;
    position: absolute !important;
    display: block !important;
    width: 6px !important;
    right: -20px !important;
  }
  .ant-tree-list-scrollbar-thumb {
    background-color: #0072ca !important;
    width: 6px !important;
    height: 201px !important;
  }

  .ant-tree-node-content-wrapper {
    background: transparent !important;
    color: #faf219;
  }
  .ant-tree-node-content-wrapper:hover {
    background: transparent !important;
    color: #faf219;
  }
  .ant-tree-node-content-wrapper:focus {
    color: #faf219 !important;
  }
  .anticon-down-circle {
    font-size: 16px !important;
  }
  background: transparent !important;
  .ant-tree-list-holder {
    margin: 65px 0 0 70px;
    font-size: 16px;
    color: #b2e3ff;
  }
  .ant-tree-treenode {
    padding: 0 0px 25px 2px !important;
  }
`;

const { TreeNode } = Tree;

const treeData = [
  {
    value: "0",
    defaultValue: "0",
    key: "0",
    parentKey: "0",
    isEditable: false,
    children: [
      {
        value: "0-1",
        key: "0-1",
        defaultValue: "0-1",
        isEditable: false,
      },
      {
        value: "0-2",
        key: "0-2",
        defaultValue: "0-2",
        isEditable: false,
      },
    ],
  },
];

const expandedKeyArr = ["0"];
export default function Demo() {
  const [data, setData] = useState(treeData);
  const [expandedKeys, setExpandedKeys] = useState(expandedKeyArr);

  const onExpand = (expandedKeys: any) => {
    //记录折叠的key值
    setExpandedKeys(expandedKeys);
  };
  const renderTreeNodes = (data: any) => {
    let nodeArr = data.map((item: any) => {
      if (item.isEditable) {
        item.title = (
          <div>
            <input
              value={item.value || ""}
              onChange={(e) => onChange(e, item.key)}
            />

            <CloseOutlined
              style={{ marginLeft: 10 }}
              onClick={() => onClose(item.key, item.defaultValue)}
            />

            <CheckOutlined
              style={{ marginLeft: 10 }}
              onClick={() => onSave(item.key)}
            />
          </div>
        );
      } else {
        item.title = (
          <div>
            <span>{item.value}</span>
            <span>
              <EditOutlined
                style={{ marginLeft: 10 }}
                onClick={() => onEdit(item.key)}
              />

              <PlusOutlined
                style={{ marginLeft: 10 }}
                onClick={() => onAdd(item.key)}
              />
              {item.parentKey === "0" ? null : (
                <MinusOutlined
                  style={{ marginLeft: 10 }}
                  onClick={() => onClickDelete(item.key)}
                />
              )}
            </span>
          </div>
        );
      }

      if (item.children) {
        return (
          <TreeNode title={item.title} key={item.key}>
            {renderTreeNodes(item.children)}
          </TreeNode>
        );
      }

      return <TreeNode title={item.title} key={item.key} />;
    });

    return nodeArr;
  };

  const onAdd = (key: any) => {
    if (expandedKeys.indexOf(key) === -1) {
      expandedKeyArr.push(key);
    }
    setExpandedKeys(expandedKeyArr.slice());

    addNode(key, treeData);
    //useState里数据务必为immutable (不可赋值的对象),所以必须加上slice()返回一个新的数组对象
    setData(treeData.slice());
  };

  const onEdit = (key: any) => {
    editNode(key, treeData);
    setData(treeData.slice());
  };

  const editNode = (key: any, data: any) =>
    data.forEach((item: any) => {
      if (item.key === key) {
        item.isEditable = true;
      } else {
        item.isEditable = false;
      }
      item.value = item.defaultValue; // 当某节点处于编辑状态,并改变数据,点击编辑其他节点时,此节点变成不可编辑状态,value 需要回退到 defaultvalue
      if (item.children) {
        editNode(key, item.children);
      }
    });

  const addNode = (key: any, data: any) =>
    data.forEach((item: any) => {
      if (item.key === key) {
        if (item.children) {
          item.children.push({
            value: "default",
            key: nanoid(), // 这个 key 是唯一的
          });
        } else {
          item.children = [];
          item.children.push({
            value: "default",
            key: nanoid(),
          });
        }
        return;
      }
      if (item.children) {
        addNode(key, item.children);
      }
    });

  const onChange = (e: any, key: any) => {
    changeNode(key, e.target.value, treeData);
    setData(treeData.slice());
  };

  const changeNode = (key: any, value: any, data: any) =>
    data.forEach((item: any) => {
      if (item.key === key) {
        item.value = value;
      }
      if (item.children) {
        changeNode(key, value, item.children);
      }
    });

  const onSave = (key: any) => {
    saveNode(key, treeData);
    setData(treeData.slice());
  };

  const saveNode = (key: any, data: any) =>
    data.forEach((item: any) => {
      if (item.key === key) {
        item.defaultValue = item.value;
      }
      if (item.children) {
        saveNode(key, item.children);
      }
      item.isEditable = false;
    });

  const onClose = (key: any, defaultValue: any) => {
    closeNode(key, defaultValue, treeData);
    setData(treeData);
  };

  const closeNode = (key: any, defaultValue: any, data: any) =>
    data.forEach((item: any) => {
      item.isEditable = false;
      if (item.key === key) {
        item.value = defaultValue;
      }
      if (item.children) {
        closeNode(key, defaultValue, item.children);
      }
    });
  const [isModalVisible, setIsModalVisible] = useState(false);
  const [confirmLoading, setConfirmLoading] = useState(false);
  const [treeKey, steTreeKey] = useState();

  const onClickDelete = (key: any) => {
    setIsModalVisible(true);
    steTreeKey(key);
  };
  const deleteNode = (key: any, data: any) =>
    data.forEach((item: any, index: any) => {
      if (item.key === key) {
        data.splice(index, 1);
        return;
      } else {
        if (item.children) {
          deleteNode(key, item.children);
        }
      }
    });
  const onDelete = (treeKey: any) => {
    setData(treeData.slice());
    // console.log(treeKey);
    deleteNode(treeKey, treeData);
  };
  const handleOk = (key: any) => {
    setConfirmLoading(true);
    setTimeout(() => {
      onDelete(treeKey);
      setIsModalVisible(false);
      setConfirmLoading(false);
    }, 2000);
  };
  const handleCancel = () => {
    setIsModalVisible(false);
  };

  return (
    <div>
      <Doctree
        switcherIcon={<DownCircleOutlined />}
        expandedKeys={expandedKeys}
        onExpand={onExpand}
        height={753}
        treeData={data}
      >
        {renderTreeNodes(data)}
      </Doctree>
      <CommonModal
        closable={false}
        centered={true}
        mask={false}
        footer={null}
        title={null}
        visible={isModalVisible}
      >
        <p className={"modaltitle"}>提示</p>
        <p className={"modalcontent"}>是否确定删除?</p>
        <Button
          className={"queding"}
          loading={confirmLoading}
          onClick={handleOk}
        >
          确定
        </Button>
        <Button className={"quxiao"} onClick={handleCancel}>
          取消
        </Button>
      </CommonModal>
    </div>
  );
}

  • 写回答

1条回答 默认 最新

      报告相同问题?

      相关推荐 更多相似问题

      问题事件

      • 系统已结题 11月16日
      • 已采纳回答 11月8日
      • 创建了问题 9月29日

      悬赏问题

      • ¥20 有ASP .NET MVC做的小说阅读网站吗?
      • ¥20 beeline客户端支持ipv6地址连接hive服务
      • ¥15 香农解码的代码问题,无法输出解码结果
      • ¥15 Python操作注册表
      • ¥45 入门级别的一段VUE前端拍照像后端发送请求的代码,帮排错
      • ¥15 anaconda打开spyder后一直闪退,不知道怎么办
      • ¥15 解决迷宫问题中无法运行的问题
      • ¥15 关于aspnetcore中使用mqttnet库的entire
      • ¥15 关于#python#的问题,请各位专家解答!
      • ¥100 关于远控软件的两个问题