处理树状结构/递归数据以及 React渲染



方法1: 循环12次, 性能较高

<script>
  const data = [{
      area_code: 43,
      area_name: '湖南省'
    },
    {
      area_code: 42,
      area_name: '湖北省'
    },
    {
      area_code: 23,
      area_name: '河南省'
    },
    {
      area_code: 4,
      area_name: '北京市'
    },
    {
      area_code: 4301,
      area_name: '长沙市',
      parent_code: 43
    },
    {
      area_code: 430101,
      area_name: '芙蓉区',
      parent_code: 4301
    },
    {
      area_code: 430102,
      area_name: '天心区',
      parent_code: 4301
    },
    {
      area_code: 4302,
      area_name: '湘潭市',
      parent_code: 43
    },
    {
      area_code: 4201,
      area_name: '武冈',
      parent_code: 42
    },
    {
      area_code: 2301,
      area_name: '开封市',
      parent_code: 23
    },
    {
      area_code: 401,
      area_name: '朝阳区',
      parent_code: 4
    },
    {
      area_code: 402,
      area_name: '海定区',
      parent_code: 4
    },
  ]
  function transformTree(data, initCode) {
    function tree(id) {
      const arr = [];
      data.
      filter(item => item.parent_code === id).
      forEach(element => {
        arr.push({
          label: element.area_name,
          area_code: element.area_code,
          children: tree(element.area_code)
        })
      });
      return arr;
    }
    return tree(initCode);
  }
  const result = transformTree(data, undefined);
console.log(666, result); </script>

 

方法2: 循环144次, 性能较低

 function transformTree2(data, initCode) {
    const cloneData = JSON.parse(JSON.stringify(data));
    return cloneData.filter(father => {
      const children = cloneData.filter(child => father.area_code === child.parent_code)
      children.length > 0 ? father.children = children : null;
      return father.parent_code === initCode;
    })
  }

React 渲染 

class渲染

import React, { Component } from "react";

const treeData = {
  title: "总览",
  key: "big-title",
  children: [
    {
      title: "0-0",
      key: "0-0",
      children: [
        {
          title: "0-0-0",
          key: "0-0-0",
          children: [
            { title: "0-0-0-0", key: "0-0-0-0" },
            { title: "0-0-0-1", key: "0-0-0-1" },
            { title: "0-0-0-2", key: "0-0-0-2" },
          ],
        },
        {
          title: "0-0-1",
          key: "0-0-1",
          children: [
            { title: "0-0-1-0", key: "0-0-1-0" },
            { title: "0-0-1-1", key: "0-0-1-1" },
            { title: "0-0-1-2", key: "0-0-1-2" },
          ],
        },
        {
          title: "0-0-2",
          key: "0-0-2",
        },
      ],
    },
    {
      title: "0-1",
      key: "0-1",
      children: [
        { title: "0-1-0-0", key: "0-1-0-0" },
        { title: "0-1-0-1", key: "0-1-0-1" },
        { title: "0-1-0-2", key: "0-1-0-2" },
      ],
    },
    {
      title: "0-2",
      key: "0-2",
    },
  ],
};

class Tree extends Component {
  constructor(props) {
    super(props);
    this.state = {
      isOpen: false,
    };
  }
  get isFolder() {
    return this.props.treeData.children && this.props.treeData.children.length;
  }
  toggle = () => {
    this.setState({
      isOpen: !this.state.isOpen
    })
  }
  render() {
    return (
      <ul>
        <li>
          <div style={{cursor: 'pointer'}} onClick={this.toggle}>
            {this.props.treeData.title}
            <span>
              {this.isFolder ? (this.state.isOpen ? " -" : " +") : null}
            </span>
          </div>
          {this.isFolder ? (
            <div style={{ display: this.state.isOpen ? "block" : "none" }}>
              {this.props.treeData.children.map((item) => (
                <TreeNode treeData={item} key={item.key} />
              ))}
            </div>
          ) : null}
        </li>
      </ul>
    );
  }
}

class TreeTest extends Component {
  constructor(props) {
    super(props);
  }
  render() {
    return (
      <div>
        <h1>Tree Demo</h1>
        <TreeNode treeData={treeData} />
      </div>
    );
  }
}

export default Tree;

Hooks渲染

const data = {
    id: 0,
    post: '指挥长',
    name: '555',
    children: [
        {
            name: '某某某',
            mobile: 123456789,
        },
    ],
    postChildren: [{
        id: 1,
        name: '',
        post: '副指挥长',
        level: 2,
        children: [
            {
                id: 2,
                name: '某某某1',
                post: '',
                mobile: 123456781,
                children: [],
            },
            {
                id: 3,
                name: '某某某2',
                post: '',
                mobile: 123456782,
                children: [],
            },
            {
                id: 4,
                name: '某某某3',
                post: '',
                mobile: 123456783,
                children: [],
            },
        ],
        postChildren: [
            {
                id: 5,
                name: '',
                post: '综合协调组',
                level: 3,
                children: [
                    {
                        id: 6,
                        name: '某某某4',
                        post: '喽啰',
                        mobile: 123456784,
                        children: [],
                    },
                    {
                        id: 7,
                        name: '某某某5',
                        post: '喽啰',
                        mobile: 123456785,
                        children: [],
                    },
                    {
                        id: 8,
                        name: '某某某6',
                        post: '喽啰',
                        mobile: 123456786,
                        children: [],
                    },
                ],
            },
            {
                id: 9,
                name: '',
                level: 3,
                post: '综合协调组',
                children: [
                    {
                        id: 10,
                        name: '某某某7',
                        post: '喽啰',
                        mobile: 123456784,
                        children: [],
                    },
                    {
                        id: 11,
                        name: '某某某8',
                        post: '喽啰',
                        mobile: 123456785,
                        children: [],
                    },
                    {
                        id: 12,
                        name: '某某某9',
                        post: '喽啰',
                        mobile: 123456786,
                        children: [],
                    },
                ],
            }],
    }],

};

import React, { useState } from 'react';

function TreeNode({ treeData, treeData: { postChildren, children }, className, onClick }) {
    const [open, setOpen] = useState(true);
    const isFolder = () => postChildren && postChildren.length;

    const toggle = () => {
        setOpen(!open);
    };

    const handleLevel = (lx) => {
        let level = 'level1';
        if (lx === 2) {
            level = 'level2';
        }
        if (lx === 3) {
            level = 'level3';
        }
        return level;
    };

    return (
        <div>
            <div
                className={`item${className ? ` ${className}` : ''}`}
                onClick={(e) => {
                    onClick(treeData, e.target);
                }}
            >
                <li>
                    <div style={{ cursor: 'pointer' }}>
                        <div className={`detail${open ? ' open' : ''}`}>
                            <i
                                className="iconfont iconsanjiaoxing"
                                onClick={(e) => {
                                    e.stopPropagation();
                                    toggle();
                                }}
                            />
                            <span className="post">{treeData.post && treeData.post}</span>
                            <div>
                                <i className="iconfont iconwode mr-7" />
                                <span>{children && children.length}</span>
                            </div>
                        </div>
                        {
                            children && children.map(({ name, mobile }) => (
                                <div
                                    className="second detail"
                                    style={{ display: open ? 'flex' : 'none' }}
                                    key={name}
                                >
                                    <span className="name">{name}</span>
                                    <div>
                                        <span className="mobile">{mobile}</span>
                                        <i className="iconfont iconzixunrexian theme-color" />
                                    </div>
                                </div>
                            ))
                        }
                    </div>

                </li>
            </div>
            <ul>
                {isFolder ? (
                    <div style={{ display: open ? 'block' : 'none' }}>
                        {postChildren && postChildren.map((item) => (
                            <div
                                key={item.id}
                            >
                                <TreeNode
                                    treeData={item}
                                    onClick={onClick}
                                    className={handleLevel(item.level)}
                                />
                            </div>
                        ))}
                    </div>
                ) : null}
            </ul>
        </div>
    );
}

function Tree({ onClick }) {

    return (
        <div style={{ marginRight: 10 }}>
            <TreeNode
                treeData={data}
                onClick={onClick}
            />
        </div>
    );
}

export default Tree;

 

scss

  .content {
    display: flex;
    align-items: flex-start;
    max-height: 533px;
    .header {
      color: #fff;
      margin-bottom: 10px;
    }
    .content-left {
      max-height: 533px;
      overflow-y: scroll;
      width: 30%;
      margin-right: 15px;
      color: #fff;

      .item {
        //display: none;
        padding: 18px 8px 9px 32px;
        background-color: rgba(0, 251, 255, .05);
        margin-bottom: 2px;
        position: relative;
        cursor: pointer;
        &:link {
          box-shadow: 0 0 20px 8px rgba(134, 158, 123, 1) inset;
        }
      }
      .level2 {
        padding: 18px 8px 9px 37px;
        .iconsanjiaoxing {
          left: 13px;
        }
      }
      .level3 {
        padding: 18px 8px 9px 42px;
        .iconsanjiaoxing {
          left: 18px;
        }
      }


      .item3 {
        .iconsanjiaoxing {
          left: 18px;
        }
      }


      .second {
        padding: 18px 0 17px;
        border-bottom: 1px solid rgba(0, 251, 255, .1);
        font-size: .875rem;
        cursor: pointer;
        &:last-child {
          border-bottom: none;
        }
      }
      .open {

        .iconsanjiaoxing {
          transform: rotate(-45deg);
        }
      }
      .iconsanjiaoxing {
        position: absolute;
        left: 8px;
        top: 23px;
        margin-right: 18px;
        font-size: .75rem;
        color: #39FBF7;
        transform: rotate(-90deg);
        transition: transform .2s linear;
      }
      .mobile {
        color: rgba(255, 255, 255, .6);
        font-size: .75rem;
        margin-right: 10px;
      }

      .name {
        color: rgba(255, 255, 255, .8);
        font-size: .875rem;
      }

      .active {
        box-shadow: 0 0 20px 8px rgba(134, 158, 123, 1) inset;
      }

      .post {
        font-weight: bold;
      }

      .detail {
        display: flex;
        align-items: center;
        justify-content: space-between;
      }

      &::-webkit-scrollbar-track-piece {
        background-color: transparent;
        padding-left: 20px;
      }

      &::-webkit-scrollbar {
        width: 3px;
        height: 3px;
        margin-left: 20px;
      }

      &::-webkit-scrollbar-thumb {
        background-color: #00FBFF;
        background-clip: padding-box;
        border-radius: 1px;
        margin-left: 20px;
        padding-left: 20px;
      }

      &::-webkit-scrollbar-thumb:hover {
        background-color: #00FBFF;
      }
    }

    .content-right {
      max-height: 533px;
      overflow-y: scroll;
      width: 70%;
      color: #fff;

      & > div {
        border: 1px solid rgba(0, 251, 255, .2);
        margin-right: 10px;
        padding: 18px 25px;
      }

      &::-webkit-scrollbar-track-piece {
        background-color: transparent;
      }

      &::-webkit-scrollbar {
        width: 3px;
        height: 3px;
      }

      &::-webkit-scrollbar-thumb {
        background-color: #00FBFF;
        background-clip: padding-box;
        border-radius: 1px;
      }

      &::-webkit-scrollbar-thumb:hover {
        background-color: #00FBFF;
      }

      .title {
        color: #39FBF7;
        font-weight: bold;
        font-size: 1.125rem;
      }

      .list {
        li {
          display: flex;
          align-items: center;
          justify-content: space-between;
          padding: 22px 0;
          border-bottom: 1px solid rgba(255, 255, 25, .1);

          i {
            font-size: 1.5rem;
            color: #39FBF7;
            cursor: pointer;
          }
        }
      }
    }
    .content-center {
      position: relative;
      .header {

      }
      .list {
        display: flex;
        flex-wrap: wrap;
        justify-content: space-between;
      }
      .item {
        width: 31%;
        box-sizing: border-box;
        padding: 18px 28px;
        background-color: rgba(0, 251, 255, .05);
        margin-bottom: 26px;
        position: relative;
        cursor: pointer;
        color: #fff;
        &:link {
          box-shadow: 0 0 20px 8px rgba(134, 158, 123, 1) inset;
        }
        .item-header {
          span:nth-child(1) {
            color: #00FBFF;
            font-weight: bold;
            margin-right: 16px;
          }
          span:nth-child(2) {
            color: rgba(255, 255, 255, .6);
            font-size: .75rem;
          }
        }
        .item-center {
          display: inline-block;
          margin: 8px 0 20px;
        }
      }
      .active {
        box-shadow: 0 0 20px 8px rgba(134, 158, 123, 1) inset;
      }
    }
    .content-footer {
      color: #fff;
      .pagination-detail {
        margin-right: 60px;
        font-weight: bold;
        span {
          display: inline-block;
          color: #00FBFF;
          font-size: .875rem;
          margin: 0 10px;
        }
      }
      display: flex;
      justify-content: flex-end;
    }
  }

 

posted @ 2021-06-29 16:20  一路向北√  阅读(908)  评论(0编辑  收藏  举报

web应用开发&研究 -

业精于勤而荒于嬉。

工作,使我快乐。


Font Awesome | Respond.js | Bootstrap中文网