React實(shí)踐之Tree組件的使用方法
本文介紹了React實(shí)踐之Tree組件,分享給大家,具體如下:
實(shí)現(xiàn)功能
- 渲染數(shù)據(jù)
- 展開合并
使用
數(shù)據(jù)結(jié)構(gòu):
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>
組件實(shí)現(xiàn)代碼:
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) {
// 這是點(diǎn)擊➡️ 時(shí)調(diào)用的方法
// 如果當(dāng)前這個(gè)➡️ 沒有旋轉(zhuǎn),那就設(shè)置旋轉(zhuǎn),視覺效果
e.target.style.transform = e.target.style.transform == "rotate(-90deg)" ? "rotate(0deg)" : "rotate(-90deg)"
for(let item in e.target.parentNode.parentNode.childNodes){
// 點(diǎn)擊的時(shí)候設(shè)置當(dāng)前層級(jí)的子元素素隱藏
// 操作了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){
// 這個(gè)是返回title,因?yàn)橛袝r(shí)候是點(diǎn)擊一個(gè)鏈接,所以設(shè)置了兩種情況,如果node節(jié)點(diǎn)里面有component這個(gè)節(jié)點(diǎn),那就設(shè)置成可以點(diǎn)擊跳轉(zhuǎn)
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 = []
// 每個(gè)元素的樣式,根據(jù)當(dāng)前等級(jí)來(lái)設(shè)置樣式,level1的就縮緊20px,level2的縮緊40px,一次類推,在視覺上呈現(xiàn)樹的形式
let itemStyle = {
paddingLeft: 20*parseInt(itemGroup.level.slice(5), 10)+'px'
}
// 如果當(dāng)前節(jié)點(diǎn)還有子元素,就設(shè)置一個(gè)➡️ 箭頭 ,可以點(diǎn)擊展開。
let iconChevron = classNames('fa',{'fa-chevron-down' : itemGroup.child})
// 把所有節(jié)點(diǎn)放在一個(gè)數(shù)組里面
itemGroupItem.push(
<ul>
{/* 第一個(gè)層級(jí) */}
<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>
{/* 調(diào)用tree方法 */}
{this.tree(itemGroup.child)}
</ul>
)
return itemGroupItem
}
tree(child){
let treeItem
// 如果有子元素
if(child){
// 子元素是數(shù)組的形式,把所有的子元素循環(huán)出來(lái)
treeItem = child.map((item, key) => {
// 同理,設(shè)置樣式
let itemStyle = {
paddingLeft: 20*parseInt(item.level.slice(5), 10)+'px'
}
// 同理,設(shè)置➡️
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>
{/* 如果當(dāng)前子元素還有子元素,就遞歸使用tree方法,把當(dāng)前子元素的子元素渲染出來(lái) */}
{this.tree(item.child)}
</ul>
)
})
}
return treeItem
}
render() {
return (
<div className="tree">
{ this.treeItemCroup(this.props.treeList) }
</div>
);
}
}
export default Tree;
效果圖:

DOM結(jié)構(gòu)圖


代碼我加了一些注釋,可能還是比較難理清楚邏輯 😫
當(dāng)前的邏輯我覺得有點(diǎn)混亂,希望看的朋友們能給出一點(diǎn)建議,感激不盡
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
React組件設(shè)計(jì)過(guò)程之仿抖音訂單組件
這篇文章主要介紹了React組件設(shè)計(jì)過(guò)程之仿抖音訂單組件的實(shí)現(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-07-07
React Native使用Modal自定義分享界面的示例代碼
本篇文章主要介紹了React Native使用Modal自定義分享界面的示例代碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-10-10
React實(shí)現(xiàn)一個(gè)高度自適應(yīng)的虛擬列表
這篇文章主要介紹了React如何實(shí)現(xiàn)一個(gè)高度自適應(yīng)的虛擬列表,幫助大家更好的理解和學(xué)習(xí)使用React,感興趣的朋友可以了解下2021-04-04
antd+react中upload手動(dòng)上傳單限制上傳一張
本文主要介紹了antd+react中upload手動(dòng)上傳單限制上傳一張,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-06-06
React使用Mobx6.x共享狀態(tài)問(wèn)題
這篇文章主要介紹了React使用Mobx6.x共享狀態(tài)問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-10-10
vite?+?react?+typescript?環(huán)境搭建小白入門教程
這篇文章主要介紹了vite?+?react?+typescript?環(huán)境搭建小白入門教程,本文通過(guò)示例圖文相結(jié)合給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-12-12

