前端组件库X-Design,开发Tree组件

附言:

个人的使用React开发的组件库X-Design已开源,麻烦大家去X-Design: 使用React开发的UI组件库点个star,在此谢谢大家。

X-Design已开发的组件有:

前端组件库X-Design,开发Tree组件

X-Design组件库

X-Design组件界面截图:

前端组件库X-Design,开发Tree组件

前端组件库X-Design,开发Tree组件

X-Design组件界面截图

Tree组件,即就是树组件,开发树组件的难点是什么:是如何构建子树,其实很容易想到用递归构建子树。

使用Tree组件的样子:

import Tree from '../../components/Tree'

const data = [
    {
        label: '节点1',
        val: 'node-1',
    },
    {
        label: '节点2',
        val: 'node-2',
        children: [
            {
                label: '节点2-1',
                val: 'node-2-1',
            },
            {
                label: '节点2-2',
                val: 'node-2-2',
            },
        ]
    },
    {
        label: '节点3',
        val: 'node-3',
        children: [
            {
                label: '节点3-1',
                val: 'node-3-1',
                children: [
                    {
                        label: '节点3-1-1',
                        val: 'node-3-1-1',
                    },
                    {
                        label: '节点3-1-2',
                        val: 'node-3-1-2',
                    },
                ]
            },
        ]
    },
]

const MyTree = () => {

    const handleChange = (val, label, isSelected) => {
        console.log(val, label, isSelected);
    }

    return 
        
    
}

export default MyTree

有些参数解释一下treeData代表的就是节点树数据,showCheckbox代表节点名称前面是否显示复选框,onChange代表的是点击节点的事件。其他参数和功能后续完善。

Tree组件:

没有复选框的样子:

前端组件库X-Design,开发Tree组件

Tree组件

有复选框的样子:

前端组件库X-Design,开发Tree组件

带复选框的树组件

树组件代码:

import { useState, useMemo, Fragment } from 'react'
import DownTriangle from '../Icons/DownTriangleIcon'
import RightTriangle from '../Icons/RightTriangleIcon'
import './index.css'

const Tree = (props) => {
    const [treeData, setTreeData] = useState(props.treeData || [])

    const handleInitTreeData = (data, field, type, node) => {
        let arr = []
        function loop(data) {
            return data.map(item => {
                if(type === 'init') {
                    item[field] = false
                } else if(type === 'update' && node.val === item.val) {
                    item[field] = !item[field]
                }
                if(item.children && Array.isArray(item.children)) {
                    item.children = loop(item.children)
                }
                return item
            })
        }
        arr = loop([...data])
        return arr
    }

    const tempData = useMemo(() => {
        return handleInitTreeData([...props.treeData], 'isSelected', 'init')
    }, [props.treeData])

    

    const clickTreeNode = (node) => {
        let arr = []
        arr = handleInitTreeData([...treeData], 'isSelected', 'update', node)
        setTreeData(arr)
        props.onChange && props.onChange(node.val, node.label, node.isSelected)
    }

    const renderTree = (treeDataArr) => {
        let arr = []
        function loop(data, level) {
            return data.map(item => {
                let newLevel = level + 1
                return 
                     {clickTreeNode(item)}}
                    >
                        {
                            (item.children && item.children.length > 0) ?
                            (item.isSelected ?  : )
                            :
                            
                        }
                        {
                            props.showCheckbox ?
                            
                            : null
                        }
                        
                            {
                                item.label
                            }
                        
                    
                    {
                        item.isSelected ?
                        
                            {
                                item.children ? 
                                loop(item.children, newLevel)
                                : null
                            }
                        
                        : null
                    }
                
            })
        }
        arr = loop([...treeDataArr], 0)
        return arr
    }

    return 
        {
            renderTree(tempData)
        }
    
}

export default Tree

index.css文件:

.tree-container {}

.tree-node-label {
    display: flex;
    cursor: pointer;
}

.tree-node-label:hover {
    color: #00d5ff;
}

.tree-node-label-left-empty {
    display: inline-block;
    width: 16px;
    height: 16px;
}

在Tree组件里renderTree函数是重点,renderTree是构建树结构的函数,使用了递归,level参数是标明树在第几层,利用newLevel设置每个节点距离左边的padding距离,以构建出树状。

目前写的功能能够满足基本功能,后续在完善其它功能。

未完,待续。。。

发表评论
留言与评论(共有 0 条评论) “”
   
验证码:

相关文章

推荐文章