React实践之Tree组件

前端之家收集整理的这篇文章主要介绍了React实践之Tree组件前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

React实践之Tree组件

实现功能

  • 渲染数据
  • 展开合并

使用

  • 数据结构:
const node = {
  title: '00000',key: '0',level:'level1',open: true,child:[  
      {
        title: '0-111111',key: '0-0',level:'level2',child:[  
            {  
              title: '0-1-1111',key: '0-0-0',level:'level3',},{  
              title: '0-1-2222',key: '0-0-1',child: [
                  {  
                  title: '0-1-2-11111',key: '0-0-1-0',level:'level4',child: [
                      {  
                      title: '0-1-2-1-111',key: '0-0-1-0-0',level:'level5',}
                  ]
                }
              ]
            },{  
              title: '0-1-33333',key: '0-0-4',]
      },{
        title: '0-222222',key: '0-2',open: false,child: [
          {
            title: '0-2-1111',key: '0-2-0',{
            title: '0-2-22222',key: '0-2-1',{
            title: '0-2-33333',key: '0-2-2',}
        ]
      }
  ]
}
<div>
    <Tree 
        treeList = {node}
    /> 
</div>
import React,{ Component } from 'react';
import classNames from 'classnames';
const history = createHistory();
import {
    BrowserRouter as Router,HashRouter,Route,Link,Switch,NavLink
  } from 'react-router-dom';

class Tree extends Component {

    constructor(props){
        super(props)
        this.treeItemCroup    = this.treeItemCroup.bind(this);
        this.handleClick      = this.handleClick.bind(this);

        this.state ={
            openList : false
        }
    }

    handleClick(e) {
        // 这是点击➡️ 时调用方法
        // 如果当前这个➡️ 没有旋转,那就设置旋转,视觉效果
        e.target.style.transform = e.target.style.transform == "rotate(-90deg)" ? "rotate(0deg)" : "rotate(-90deg)"
        for(let item in e.target.parentNode.parentNode.childNodes){
            // 点击的时候设置当前层级的子元素素隐藏
            // 操作了DOM,我很难受
            if(item > 0){
                e.target.parentNode.parentNode.childNodes[item].style.display = e.target.parentNode.parentNode.childNodes[item].style.display === 'none' ? 'block' : 'none' 
            }
        }
    }
    
    itemTitle(item){
        // 这个是返回title,因为有时候是点击一个链接,所以设置了两种情况,如果node节点里面有component这个节点,那就设置成可以点击跳转
        if(item.component){ 
            return (<Link to={ item.component } >
                         <span onClick={this.handleClick.bind(this)}>{item.title}</span>
                    </Link>)
        }else{
            return (
                 <span onClick={this.handleClick.bind(this)}>{item.title}</span>
            )
        }
    }

    treeItemCroup(itemGroup) {
        let itemGroupItem = []
        // 每个元素的样式,根据当前等级来设置样式,level1的就缩紧20px,level2的缩紧40px,一次类推,在视觉上呈现树的形式
        let itemStyle = {
                paddingLeft: 20*parseInt(itemGroup.level.slice(5),10)+'px'
            }
        // 如果当前节点还有子元素,就设置一个➡️ 箭头 ,可以点击展开。
        let iconChevron = classNames('fa',{'fa-chevron-down' : itemGroup.child})
        // 把所有节点放在一个数组里面
        itemGroupItem.push(
            <ul>
                {/* 第一个层级 */}
                <li className={itemGroup.level} key={itemGroup.key} style={itemStyle}>
                    <i aria-hidden="true" className={iconChevron} onClick={this.handleClick.bind(this)}></i>
                    {this.itemTitle(itemGroup)}
                </li>
                {/* 调用tree方法 */}
                {this.tree(itemGroup.child)}
            </ul>
        )
        return itemGroupItem
    }

    tree(child){
        let treeItem
        // 如果有子元素
        if(child){  
            // 子元素是数组的形式,把所有的子元素循环出来
            treeItem = child.map((item,key) => {
                // 同理,设置样式
                let itemStyle = {
                    paddingLeft: 20*parseInt(item.level.slice(5),10)+'px'
                }
                // 同理,设置➡️ 
                let iconChevron = classNames('fa',{'fa-chevron-down' : item.child})
                return  (
                    <ul>
                        <li className={item.level} key={key} style={itemStyle}>
                           <i aria-hidden="true" className={iconChevron} onClick={this.handleClick.bind(this)}></i>
                            {this.itemTitle(item)}
                        </li>
                        {/* 如果当前子元素还有子元素,就递归使用tree方法,把当前子元素的子元素渲染出来 */}
                        {this.tree(item.child)}
                    </ul>
                )
            })
        }
        return treeItem
    }

    render() {
        return (
            <div className="tree">
                { this.treeItemCroup(this.props.treeList) }
            </div>
        );
    }
}

export default Tree;

代码我加了一些注释,可能还是比较难理清楚逻辑 原文链接:https://www.f2er.com/react/302670.html

猜你在找的React相关文章