React实践之Tree组件的使用方法


Posted in Javascript onSeptember 30, 2017

本文介绍了React实践之Tree组件,分享给大家,具体如下:

实现功能

  • 渲染数据
  • 展开合并

使用

数据结构:

const node = {
 title: '00000', 
 key: '0' ,
 level:'level1',
 open: true,
 child:[ 
   {
    title: '0-111111', 
    key: '0-0',
    level:'level2',
    open: true,
    child:[ 
      { 
       title: '0-1-1111', 
       key: '0-0-0',
       level:'level3',  
      }, 
      { 
       title: '0-1-2222', 
       key: '0-0-1',
       level:'level3',
       open: true,
       child: [
         { 
         title: '0-1-2-11111', 
         key: '0-0-1-0',
         level:'level4',
         open: true,
         child: [
           { 
           title: '0-1-2-1-111', 
           key: '0-0-1-0-0',
           level:'level5',
          }
         ]
        }
       ]
      },
      { 
       title: '0-1-33333', 
       key: '0-0-4',
       level:'level3',
      }, 
    ]
   },
   {
    title: '0-222222', 
    key: '0-2',
    level:'level2',
    open: false,
    child: [
     {
      title: '0-2-1111', 
      key: '0-2-0',
      level:'level3',
     },
     {
      title: '0-2-22222', 
      key: '0-2-1',
      level:'level3',
     },
     {
      title: '0-2-33333', 
      key: '0-2-2',
      level:'level3',
     }
    ]
   }
 ]
}

引用代码:

<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;

效果图:

React实践之Tree组件的使用方法

DOM结构图

React实践之Tree组件的使用方法

React实践之Tree组件的使用方法

代码我加了一些注释,可能还是比较难理清楚逻辑 ?

当前的逻辑我觉得有点混乱,希望看的朋友们能给出一点建议,感激不尽

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
JavaScript OOP类与继承
Nov 15 Javascript
js 实现复制到粘贴板的功能代码
May 13 Javascript
javascript之querySelector和querySelectorAll使用说明
Oct 09 Javascript
JS读取cookies信息(记录用户名)
Jan 10 Javascript
js控制当再次点击按钮时的间隔时间
Jun 03 Javascript
js带前后翻页的图片切换效果代码分享
Sep 08 Javascript
angularjs 表单密码验证自定义指令实现代码
Oct 27 Javascript
简单实现JS上传图片预览功能
Apr 14 Javascript
Vue filter介绍及其使用详解
Oct 21 Javascript
React+TypeScript+webpack4多入口配置详解
Aug 08 Javascript
原生js实现随机点餐效果
Dec 10 Javascript
node.js 如何监视文件变化
Sep 01 Javascript
JS动态添加的div点击跳转到另一页面实现代码
Sep 30 #Javascript
Node.js微信 access_token ( jsapi_ticket ) 存取与刷新的示例
Sep 30 #Javascript
jqgrid实现简单的单行编辑功能
Sep 30 #Javascript
微信小程序富文本渲染引擎的详解
Sep 30 #Javascript
js实现数组和对象的深浅拷贝
Sep 30 #Javascript
node通过express搭建自己的服务器
Sep 30 #Javascript
react-native中ListView组件点击跳转的方法示例
Sep 30 #Javascript
You might like
php var_export与var_dump 输出的不同
2013/08/09 PHP
php socket客户端及服务器端应用实例
2014/07/04 PHP
WordPress分页伪静态加html后缀
2016/06/08 PHP
利用js判断浏览器类型(是否为IE,Firefox,Opera浏览器)
2013/11/22 Javascript
jQuery控制TR显示隐藏的三种常用方法
2014/08/21 Javascript
jquery实现上下左右滑动的方法
2015/02/09 Javascript
JS实现简洁、全兼容的拖动层实例
2015/05/13 Javascript
jQuery验证表单格式的使用方法
2017/01/10 Javascript
js实现随机数字字母验证码
2017/06/19 Javascript
Bootstrap Table 搜索框和查询功能
2017/11/30 Javascript
微信小程序实现YDUI的ScrollNav组件
2018/02/02 Javascript
nginx+vue.js实现前后端分离的示例代码
2018/02/12 Javascript
JavaScript实现的简单Tab点击切换功能示例
2018/07/06 Javascript
java遇到微信小程序 &quot;支付验证签名失败&quot; 问题解决
2019/12/22 Javascript
vue实现的多页面项目如何优化打包的步骤详解
2020/07/19 Javascript
Js数组扁平化实现方法代码总汇
2020/11/11 Javascript
js实现纯前端压缩图片
2020/11/16 Javascript
[00:12]2018DOTA2亚洲邀请赛 Somnus丶M出阵单挑
2018/04/06 DOTA
[00:32]2018DOTA2亚洲邀请赛出场——VP
2018/04/04 DOTA
Python环境变量设置方法
2016/08/28 Python
深入理解NumPy简明教程---数组2
2016/12/17 Python
python中的随机函数小结
2018/01/27 Python
Python使用wxPython实现计算器
2018/01/30 Python
python3利用Dlib19.7实现人脸68个特征点标定
2018/02/26 Python
Python使用matplotlib绘图无法显示中文问题的解决方法
2018/03/14 Python
python中sys.argv函数精简概括
2018/07/08 Python
用Django写天气预报查询网站
2018/10/21 Python
基于python traceback实现异常的获取与处理
2019/12/13 Python
opencv+python实现均值滤波
2020/02/19 Python
Python callable内置函数原理解析
2020/03/05 Python
基于Python把网站域名解析成ip地址
2020/05/25 Python
什么是Python中的顺序表
2020/06/02 Python
python实现定时发送邮件
2020/12/23 Python
下面代码从性能上考虑,有什么问题
2015/04/03 面试题
2016新年致辞
2015/08/01 职场文书
numpy array找出符合条件的数并赋值的示例代码
2022/06/01 Python