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 相关文章推荐
js控制表单操作的常用代码小结
Aug 15 Javascript
JavaScript图片放大技术(放大镜)实现代码分享
Nov 14 Javascript
动态加载iframe时get请求传递中文参数乱码解决方法
May 07 Javascript
javascript实现Table间隔色以及选择高亮(和动态切换数据)的方法
May 14 Javascript
Jquery使用css方法改变样式实例
May 18 Javascript
json实现添加、遍历与删除属性的方法
Jun 17 Javascript
JavaScript 数组的深度复制解析
Nov 02 Javascript
BootStrap中关于Select下拉框选择触发事件及扩展
Nov 22 Javascript
老生常谈ES6中的类
Jul 31 Javascript
动态Axios的配置步骤详解
Jan 12 Javascript
vue slot与传参实例代码讲解
Apr 28 Javascript
vue/cli 配置动态代理无需重启服务的方法
May 20 Vue.js
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
全国FM电台频率大全 - 21 海南省
2020/03/11 无线电
PHP中的integer类型使用分析
2010/07/27 PHP
ThinkPHP入口文件设置及相关注意事项分析
2014/12/05 PHP
Laravel 5.4重新登录实现跳转到登录前页面的原理和方法
2017/07/13 PHP
PHP中的浅复制与深复制的实例详解
2017/10/26 PHP
PHP面向对象程序设计之接口的继承定义与用法详解
2018/12/20 PHP
PHP简单验证码功能机制实例详解
2019/03/27 PHP
Yii2.0框架behaviors方法使用实例分析
2019/09/30 PHP
用javascript自动显示最后更新时间
2007/03/15 Javascript
jQuery实现延迟跳转的方法
2015/06/05 Javascript
学习Javascript面向对象编程之封装
2016/02/23 Javascript
轻松掌握jQuery中wrap()与unwrap()函数的用法
2016/05/24 Javascript
JS实现的表头列头固定页面功能示例
2017/01/10 Javascript
微信小程序组件 marquee实例详解
2017/06/23 Javascript
js实现rem自动匹配计算font-size的示例
2017/11/18 Javascript
详解解决Vue相同路由参数不同不会刷新的问题
2018/10/12 Javascript
JavaScript动态添加数据到表单并提交的几种方式
2019/06/26 Javascript
js定义类的方法示例【ES5与ES6】
2019/07/30 Javascript
微信小程序实现组件顶端固定或底端固定效果(不随滚动而滚动)
2020/04/09 Javascript
vue 页面跳转的实现方式
2021/01/12 Vue.js
javascript实现简单留言板案例
2021/02/09 Javascript
[55:18]Liquid vs Chaos 2019国际邀请赛小组赛 BO2 第一场 8.15
2019/08/16 DOTA
Python文本统计功能之西游记用字统计操作示例
2018/05/07 Python
Python下调用Linux的Shell命令的方法
2018/06/12 Python
Python检查图片是否损坏及图片类型是否正确过程详解
2019/09/30 Python
Jupyter notebook快速入门教程(推荐)
2020/05/18 Python
web字体加载方案优化小结
2019/11/29 HTML / CSS
Omio英国:搜索并比较便宜的巴士、火车和飞机
2019/08/27 全球购物
俄罗斯电动工具和设备购物网站:Vseinstrumenti.ru
2020/11/12 全球购物
运动会通讯稿400字
2014/01/28 职场文书
个人简历自我评价
2014/02/02 职场文书
公证书标准格式
2014/04/10 职场文书
个人贷款授权委托书样本
2014/10/07 职场文书
群众路线自我剖析范文
2014/11/04 职场文书
刑事法律意见书
2015/06/04 职场文书
集结号观后感
2015/06/08 职场文书