antd-tree树形组件带搜索框的实际应用

 

 需求视图

antd-tree树形组件带搜索框的实际应用_第1张图片

import React, { Component } from 'react';
import { Form, Input, Tree } from 'antd';
const TreeNode=Tree.TreeNode;

const { Search } = Input;
const treeData = [
    {
        deptName: '总部',
        deptId: 'HQ001',
        children: [
            {
                proName: '金街大厦',
                proId: 'ea23sdf',
                children: [
                    { proName: 'ceshi', proId: '15478cc' },
                    { proName: '测试项目', proId: 'cvb25sa' },
                    { proName: 'xxceshiyi', proId: 'f95esc2' },
                ],
            },
            {
                proName: '金街管理',
                proId: 'f23564d',
                children: [
                    { proName: '测试新增项目', proId: '25dfbn3' },
                    { proName: '建筑', proId: 'rt89gh2' },
                    { proName: '0-0-1-2', proId: 'sd9562v' },
                ],
            },
            {
                proName: 'haha',
                proId: '23148dg',
            },
        ],
    },
    {
        deptName: '北京',
        deptId: '548cvfg',
        children: [
            { proName: '北京1', proId: '1236llo' },
            { proName: '叨叨', proId: 'ea82ssk' },
            { proName: 'beijing', proId: 'fyu831x' },
        ],
    },
    {
        deptName: '上海',
        deptId: '54fae89',
    },
];


class Index extends Component {
    constructor(props) {
        super(props);
        this.state = {
            loading: false,
            expandedKeys: [], // 存树节点展开key
            treeData: []
            autoExpandParent: false, // 默认层级不展开
        }
    }


    expandedKeysFun = (treeData) => { // 展开 key函数
        if (treeData && treeData.length == 0) {
            return [];
        }
        //console.log(treeData)
        let arr = [];
        const expandedFn = (Data) => {
            Data.map((item, index) => {
                arr.push(item.key);
                if (item.children && item.children.length > 0) {
                    expandedKeysFn(item.children);
                }
            })
        }
        // 执行expandedFn函数,把treeData传给Data
        expandedFn(treeData);
        return arr;
    }

    // 点击搜索:若有子级符合搜索条件,显示展开过滤搜索出的子级;不符合的就不显示出来
    onSearch = (value) => {  // 搜索框
        if (value == "") { // 为空时层级不展开
            // 还要调接口刷新下页面,接口我略写
            axios.post('', {}).then(res => {})
            this.setState({
                expandedKeys: [],
                autoExpandParent: false, // 不展开层级
                loading: false,
            })
        } else {
            let res = this.arrayTreeFilter(treeData, this.filterFn, value);
            let expkey = this.expandedKeysFun(res);
            this.setState({
                expandedKeys: expkey,
                autoExpandParent: true,
            })
        }
    }

    // 过滤数据
    arrayTreeFilter = (data, predicate, filterText) => {
        const nodes = data;
        // 如果已经没有节点了,结束递归
        if (!(nodes && nodes.length)) {
            return;
        }
        const newChildren = [];
        for (const node of nodes) { // for..of循环, node即item
            if (predicate(node, filterText)) {
                // 如果自己(节点)符合条件,直接加入到新的节点集
                newChildren.push(node);
                // 并接着处理其 children,(因为父节点符合,子节点一定要在,所以这一步就不递归了)
                if(node.children && node.children.length > 0) {
                    node.children = this.arrayTreeFilter(node.children, predicate, filterText);
                }
            } else {
                // 如果自己不符合条件,需要根据子集来判断它是否将其加入新节点集
                // 根据递归调用 arrayTreeFilter() 的返回值来判断
                const subs = this.arrayTreeFilter(node.children, predicate, filterText);
                // 以下两个条件任何一个成立,当前节点都应该加入到新子节点集中
                // 1. 子孙节点中存在符合条件的,即 subs 数组中有值
                // 2. 自己本身符合条件
                if ((subs && subs.length) || predicate(node, filterText)) {
                    node.children = subs;
                    newChildren.push(node);
                }
            }
        }
        return newChildren;
    }

     //过滤函数
    filterFn = (data, filterText) => {
        if (!filterText) {
            return true;
        }
        return (
            new RegExp(filterText, "i").test(data.deptName|| data.proName) //根据xxname过滤 ,因为父级name与子级name不一样,写个||
        );
    }
 
    // 1. 生成树结构函数
    // 项目列表渲染的方法
    renderTreeNode = (data) => {
        if (data.length == 0) {
            return
        }
        let { expandedKeys, searchValue } = this.state;
        return data && data.length > 0 && data.map((item) => {
            if (item.children && item.children.length > 0) {
                
                return (

                    {/* 展示父级数据 */}
                    {this.renderTreeNode(item.children)}
                
                )
            }
            // 展示子级的数据
            return 
        })
    }
 
    onExpand = expandedKeys => {
        this.setState({
            expandedKeys,
            autoExpandParent: false,
        });
    };

    render() {
        const { expandedKeys, treeData, autoExpandParent, loading } = this.state;
        return (
            
项目列表
this.onSearch(value)} />
{this.renderTreeNode(treeData)}
) } } export default Index

 拓展----如果标题太长想要省略,还想要有文字提示Tooltip或者气泡卡片Popover

        部分代码:

import cutStringLength from 'utils/utils'


....

return data && data.length > 0 && data.map((item) => {
            if (item.children && item.children.length > 0) {
                
                return (
{cutStringLength(item.deptName, 20)}} dataRef={item} className={styles.listStyle}>
                    {/* 展示父级数据 */}
                    {this.renderTreeNode(item.children)}
                
                )
            }
            // 展示子级的数据
            return {cutStringLength(item.proName, 20)}} dataRef={item}>
        })




styles文件
    .listParentStyle {
        ul li {
            span:nth-child(2n){
                font-weight:600;
            }
        }
    .listStyle {
        ul li {
            span:nth-child(2n){
                font-weight:400;
            }
        }
        ul li .ant-tree-node-content-wrapper:hover {
            background-color: #f0fbff;
        }
    }
}    


utils/utils文件:
// strName 文本  len长度
export function cutStringLength (strName, len) {
    if(strName == null) {
        return ''
    }
    if(strName.length > len) {
        return `${strName.substring(0, len-1)}...`
    }
    return strName
}

参考图片

        即使不用点击文字本身,点击文字所在当前行,这行文字也会被点中,并且显示背景色

antd-tree树形组件带搜索框的实际应用_第2张图片

项目中用到Tree组件,并且还能进行搜索

代码供参考

博主写的不错:

http://t.csdnimg.cn/FSCqH

 相关文章

react–antd 实现TreeSelect树形选择组件,实现点开一层调一次接口

你可能感兴趣的:(react+antd组件,javascript,前端,react.js)