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 22 Javascript
node.js中的console.dir方法使用说明
Dec 10 Javascript
jQuery实现拖拽效果插件的方法
Mar 23 Javascript
JavaScript程序中实现继承特性的方式总结
Jun 24 Javascript
Bootstrap基本插件学习笔记之Popover提示框(19)
Dec 08 Javascript
JS实现的五级联动菜单效果完整实例
Feb 23 Javascript
JavaScript实现隐藏省略文字效果的方法
Apr 27 Javascript
JS实现动态给标签控件添加事件的方法示例
May 13 Javascript
微信小程序 按钮滑动的实现方法
Sep 27 Javascript
微信小程序的mpvue框架快速上手指南
May 15 Javascript
layui实现左侧菜单点击右侧内容区显示
Jul 26 Javascript
Vue实现手机号、验证码登录(60s禁用倒计时)
Dec 19 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
php中使用Akismet防止垃圾评论的代码
2011/06/10 PHP
PHP正则表达式替换站点关键字链接后空白的解决方法
2014/09/16 PHP
PHP+jQuery+Ajax实现用户登录与退出
2015/04/27 PHP
PHP递归统计系统中代码行数
2019/09/19 PHP
复制网页内容,粘贴之后自动加上网址的实现方法(脚本之家特别整理)
2014/10/16 Javascript
jQuery的层级查找方式分析
2016/06/16 Javascript
JS对象创建的几种方式整理
2017/02/28 Javascript
JavaScript函数参数的传递方式详解
2017/03/06 Javascript
详解vue-router基本使用
2017/04/18 Javascript
jQuery插件artDialog.js使用与关闭方法示例
2017/10/09 jQuery
详解如何在angular2中获取节点
2017/11/23 Javascript
jquery引入外部CDN 加载失败则引入本地jq库
2018/05/23 jQuery
微信小程序踩坑记录之解决tabBar.list[3].selectedIconPath大小超过40kb
2018/07/04 Javascript
jQuery实现动画、消失、显现、渐出、渐入效果示例
2018/09/06 jQuery
vue实现打印功能的两种方法
2018/09/07 Javascript
Node.js原生api搭建web服务器的方法步骤
2019/02/15 Javascript
详解JavaScript中的坐标和距离
2019/05/27 Javascript
微信小程序 高德地图路线规划实现过程详解
2019/08/05 Javascript
微信公众号服务器验证Token步骤图解
2019/12/30 Javascript
[01:04:32]DOTA2-DPC中国联赛 正赛 Aster vs LBZS BO3 第二场 2月23日
2021/03/11 DOTA
python操作redis的方法
2015/07/07 Python
python3.4实现邮件发送功能
2018/05/28 Python
pycharm+PyQt5+python最新开发环境配置(踩坑)
2019/02/11 Python
微信小程序python用户认证的实现
2019/07/29 Python
Python导入模块包原理及相关注意事项
2020/03/25 Python
python中翻译功能translate模块实现方法
2020/12/17 Python
用html5实现语音搜索框的方法
2014/03/18 HTML / CSS
Chemist Warehouse中文网:澳洲连锁大药房
2021/02/05 全球购物
资源环境与城市管理专业推荐信
2013/11/30 职场文书
普通大学毕业生自荐信范文
2014/02/23 职场文书
2014年单位植树节活动方案
2014/03/23 职场文书
舞蹈兴趣小组活动总结
2014/07/07 职场文书
2015年化妆品销售工作总结
2015/05/11 职场文书
2015年度合同管理工作总结
2015/05/22 职场文书
面试中canvas绘制图片模糊图片问题处理
2022/03/13 Javascript
td 内容自动换行 table表格td设置宽度后文字太多自动换行
2022/12/24 HTML / CSS