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 相关文章推荐
浅谈tudou土豆网首页图片延迟加载的效果
Jun 23 Javascript
javascipt基础内容--需要注意的细节
Apr 10 Javascript
JS+CSS 制作的超级简单的下拉菜单附图
Nov 22 Javascript
javascript框架设计读书笔记之模块加载系统
Dec 02 Javascript
javascript实现3D变换的立体圆圈实例
Aug 06 Javascript
基于jQuery实现动态数字展示效果
Aug 12 Javascript
详解JavaScript中jQuery和Ajax以及JSONP的联合使用
Aug 13 Javascript
JS简单获取客户端IP地址的方法【调用搜狐接口】
Sep 05 Javascript
JavaScript中创建对象的7种模式详解
Feb 21 Javascript
Javascript将图片的绝对路径转换为base64编码的方法
Jan 11 Javascript
QRCode.js二维码生成并能长按识别
Oct 16 Javascript
如何手动实现一个 JavaScript 模块执行器
Oct 16 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新手上路(九)
2006/10/09 PHP
PHP 获取客户端真实IP地址多种方法小结
2010/05/15 PHP
两种设置php载入页面时编码的方法
2014/07/29 PHP
php实现的支持断点续传的文件下载类
2014/09/23 PHP
iis6+javascript Add an Extension File
2007/06/13 Javascript
Javascript的构造函数和constructor属性
2010/01/09 Javascript
jQuery 第二课 操作包装集元素代码
2010/03/14 Javascript
JQuery 学习技巧总结
2010/05/21 Javascript
jquery中输入验证中一个不错的效果
2010/08/21 Javascript
为JS扩展Array.prototype.indexOf引发的问题及解决办法
2015/01/21 Javascript
浅谈jquery回调函数callback的使用
2015/01/30 Javascript
详解页面滚动值scrollTop在FireFox与Chrome浏览器间的兼容问题
2015/12/03 Javascript
javascript 组合按键事件监听实现代码
2017/02/21 Javascript
从零学习node.js之文件操作(三)
2017/02/21 Javascript
jquery DataTable实现前后台动态分页
2017/06/17 jQuery
JavaScript编写棋盘覆盖代码详解
2017/08/28 Javascript
vue项目中axios使用详解
2018/02/07 Javascript
jQuery实现文字超过1行、2行或规定的行数时自动加省略号的方法
2018/03/28 jQuery
JavaScript学习教程之cookie与webstorage
2019/06/23 Javascript
JavaScript 中判断变量是否为数字的示例代码
2020/10/22 Javascript
基于vue项目设置resolves.alias: '@'路径并适配webstorm
2020/12/02 Vue.js
遍历python字典几种方法总结(推荐)
2016/09/11 Python
python用pickle模块实现“增删改查”的简易功能
2017/06/07 Python
pyqt5移动鼠标显示坐标的方法
2019/06/21 Python
python把转列表为集合的方法
2019/06/28 Python
最新2019Pycharm安装教程 亲测
2020/02/28 Python
Python读取excel文件中带公式的值的实现
2020/04/17 Python
Python利用socket模块开发简单的端口扫描工具的实现
2021/01/27 Python
HTML5 语音搜索只需一句代码
2013/01/03 HTML / CSS
德国体育用品网上商店:SC24.com
2016/08/01 全球购物
Everything But Water官网:美国泳装品牌
2019/03/17 全球购物
羽毛球比赛策划方案
2014/06/13 职场文书
社团个人总结范文
2015/03/05 职场文书
运动会加油稿30字
2015/07/21 职场文书
2016入党积极分子党校培训心得体会
2016/01/06 职场文书
mysql中整数数据类型tinyint详解
2021/12/06 MySQL