antd-tree组件带搜索框的使用及踩坑(只标红)

前言:

最近再用Tree组件做项目,记录一下使用方法。

一、预期的效果

 antd-tree带搜索框的示例(官网):官网只是标红

我预期的效果是搜索并且标红(官网示例)。下面是我参考官网的示例写出来的。

二、antd-tree组件带搜索框的使用及踩坑(只标红)

import React, { Component } from 'react';
import { Tree, Input } from 'antd';
import styles from '../../assets/index.css';
const { TreeNode } = Tree;
const { Search } = Input;
class Index extends Component {
    constructor(props) {
        super(props)
        this.state = {
            data: [
                {
                    title: "十三中学",
                    key: 1,
                    children: [
                        {
                            title: "初一年级",
                            key: 2,
                            children: [
                                {
                                    title: "一班",
                                    key: 3,
                                },
                                {
                                    title: "二班",
                                    key: 4,
                                }
                            ]
                        },
                        {
                            title: "初二年级",
                            key: 20,
                        }
                    ]
                },
                {
                    title: "八十中学",
                    key: 5,
                    children: [
                        {
                            title: "初一年级",
                            key: 6,
                            children: [
                                {
                                    title: "一班",
                                    key: 7,
                                    children: [

                                    ]
                                },
                                {
                                    title: "二班",
                                    key: 8,
                                    children: [
                                        {
                                            title: "一组",
                                            key: 9,
                                            children: []
                                        },
                                        {
                                            title: "vv组",
                                            key: 999,
                                            children: []
                                        }
                                    ]
                                }
                            ]
                        },
                        {
                            title: "初二年级",
                            key: 55,
                            children: []
                        }
                    ]
                }
            ],
            expandedKeys: [], //展开的key值
            autoExpandParent: true,
            checkedKeys: [], //选中的key,
            searchValue: '',
            searchTreeKey: [] //搜索得key
        }
    }
    //给子级添加父级Key
    addParentKeyWrapper = (tree) => {
        //深度克隆
        const data = JSON.parse(JSON.stringify(tree));
        function addParentKey(data, parentKey) {
            data.forEach(ele => {
                const { children, key } = ele;
                ele.parent_key = parentKey;
                if (children) {//如果唯一标识不是code可以自行改变
                    addParentKey(children, key)
                }
            })
        }
        addParentKey(data, null); //一开始为null,根节点没有父级
        return data;
    }
    componentDidMount() {
        this.expandedKeysFn();

        this.setState({
            data: this.addParentKeyWrapper(this.state.data) //调用添加父元素key
        })
    }
    onChange = (e) => { //search变化
        const { value } = e.target;
        console.log(value)
        const dataList = [];
        if (value) {
            const generateList = data => { //tree树片扁平化
                for (let i = 0; i < data.length; i++) {
                    const node = data[i];
                    const { key, title, parent_key } = node;
                    dataList.push({ key, title: title, parent_key: parent_key }); //根据自己的数据更换parent_key代表父级key
                    if (node.children) {
                        generateList(node.children);
                    }
                }
            };
            generateList(this.state.data);

            const getParentKey = (key, tree) => { //获取父元素可以
                let parentKey;
                for (let i = 0; i < tree.length; i++) {
                    const node = tree[i];
                    if (node.children) {
                        if (node.children.some(item => item.key === key)) {
                            parentKey = node.key;
                        } else if (getParentKey(key, node.children)) {
                            parentKey = getParentKey(key, node.children);
                        }
                    }
                }
                return parentKey;
            };
           
            const expandedKeys = dataList
                .map(item => {
                    if (item.title.indexOf(value) > -1) {
                        return getParentKey(item.key, this.state.data);
                    }
                    return null;
                })
                .filter((item, i, self) => item && self.indexOf(item) === i);
        
            this.setState({
                expandedKeys: expandedKeys,
                searchValue: value,
                autoExpandParent: true
            })
        } else {
            this.expandedKeysFn() //重置展开key
            this.setState({
                searchValue: value,
                autoExpandParent: true
            })
        }
    }
    renderTreeNode = (data) => { //生成树结构函数
        if (data.length == 0) {
            return
        }
       let {searchValue}=this.state;
        return data.map((item) => {
            const index = item.title.indexOf(searchValue);
            const beforeStr = item.title.substr(0, index);
            const afterStr = item.title.substr(index + searchValue.length);
            const title =
                index > -1 ? (
                    <span>
                        {beforeStr}
                        <span style={{ color: "red" }}>{searchValue}</span>
                        {afterStr}
                    </span>
                ) : (
                    <span>{item.title}</span>
                );
            if (item.children && item.children.length > 0) {
                //className={searchTreeKey.indexOf(item.key) > -1 ? styles.yes : styles.no}
                return <TreeNode  title={title} key={item.key} >
                    {
                        this.renderTreeNode(item.children)
                    }
                </TreeNode>
            }
            return <TreeNode key={item.key} title={title}  ></TreeNode>
        })
    }
    expandedKeysFn = () => {
        let { data } = this.state;
        let arr = [];
        let loop = (data) => {
            data.map((item, index) => {
                arr.push(item.key);
                if (item.children && item.children.length > 0) {
                    loop(item.children)
                }
            })
        }
        loop(data);
        this.setState({
            expandedKeys: arr
        })
    }
    onExpand = expandedKeys => {
        console.log('onExpand', expandedKeys);
        this.setState({
            expandedKeys,
            autoExpandParent: false
        });
    };
    onCheck = (checkedKeys) => {
        this.setState({ checkedKeys })
    }
    render() {
        let { data, expandedKeys, autoExpandParent, checkedKeys } = this.state;
        return (
            <div>
                <Search style={{ marginBottom: 8 }} placeholder="Search" onChange={this.onChange} />
                <Tree
                    checkable
                    expandedKeys={expandedKeys} //默认展开的key
                    onExpand={this.onExpand} //展开事件
                    autoExpandParent={autoExpandParent} //是否自动展开父节点
                    checkedKeys={checkedKeys} //选中的key
                    onCheck={this.onCheck} //选中事件
                >
                    {this.renderTreeNode(data)}
                </Tree>
            </div>
        );
    }
}

export default Index

index.css 

.yes{
   
    display: block;
}
.no{
    display: none;
}

hook语法

import React, { Component, useEffect, useState } from 'react';
import { Tree, Input } from 'antd';
import styles from '../../assets/index.css';
const { TreeNode } = Tree;
const { Search } = Input;



function Index(props) {
    let arr = [
        {
            title: "十三中学",
            key: 1,
            children: [
                {
                    title: "初一年级",
                    key: 2,
                    children: [
                        {
                            title: "一班",
                            key: 3,
                        },
                        {
                            title: "二班",
                            key: 4,
                        }
                    ]
                },
                {
                    title: "初二年级",
                    key: 20,
                }
            ]
        },
        {
            title: "八十中学",
            key: 5,
            children: [
                {
                    title: "初一年级",
                    key: 6,
                    children: [
                        {
                            title: "一班",
                            key: 7,
                            children: [

                            ]
                        },
                        {
                            title: "二班",
                            key: 8,
                            children: [
                                {
                                    title: "一组",
                                    key: 9,
                                    children: []
                                },
                                {
                                    title: "vv组",
                                    key: 999,
                                    children: []
                                }
                            ]
                        }
                    ]
                },
                {
                    title: "初二年级",
                    key: 55,
                    children: []
                }
            ]
        }
    ]
    const [data, setData] = useState(arr); // 树形 数据
    const [expandedKeys, setExpandedKeys] = useState([]); // 展开的key值
    const [autoExpandParent, setAutoExpandParent] = useState(true); // 是否自动展开父节点
    const [checkedKeys, setCheckedKeys] = useState([]); // 选中的key
    const [searchValue, setSearchValue] = useState(""); // 搜索的值
    const [searchTreeKey, setSearchTreeKey] = useState([]); // 搜索得key

    
    useEffect(()=>{
        expandedKeysFn();
        setData(addParentKeyWrapper(data));
    },[])
    const addParentKeyWrapper = (tree) => {
        //深度克隆
        const data = JSON.parse(JSON.stringify(tree));
        function addParentKey(data, parentKey) {
            data.forEach(ele => {
                const { children, key } = ele;
                ele.parent_key = parentKey;
                if (children) {//如果唯一标识不是code可以自行改变
                    addParentKey(children, key)
                }
            })
        }
        addParentKey(data, null); //一开始为null,根节点没有父级
        return data;
    }

    const onChange = (e) => { //search变化
        const { value } = e.target;
        console.log(value)
        const dataList = [];
        if (value) {
            const generateList = data => { //tree树片扁平化
                for (let i = 0; i < data.length; i++) {
                    const node = data[i];
                    const { key, title, parent_key } = node;
                    dataList.push({ key, title: title, parent_key: parent_key }); //根据自己的数据更换parent_key代表父级key
                    if (node.children) {
                        generateList(node.children);
                    }
                }
            };
            generateList(data);

            const getParentKey = (key, tree) => { //获取父元素可以
                let parentKey;
                for (let i = 0; i < tree.length; i++) {
                    const node = tree[i];
                    if (node.children) {
                        if (node.children.some(item => item.key === key)) {
                            parentKey = node.key;
                        } else if (getParentKey(key, node.children)) {
                            parentKey = getParentKey(key, node.children);
                        }
                    }
                }
                return parentKey;
            };

            const expandedKeys = dataList
                .map(item => {
                    if (item.title.indexOf(value) > -1) {
                        return getParentKey(item.key, data);
                    }
                    return null;
                })
                .filter((item, i, self) => item && self.indexOf(item) === i);

            setExpandedKeys(expandedKeys);
            setSearchValue(value);
            setAutoExpandParent(true);
        } else {
            expandedKeysFn() //重置展开key
            setSearchValue(value);
            setAutoExpandParent(true);
        }
    }


    const renderTreeNode = (data) => { //生成树结构函数
        if (data.length == 0) {
            return
        }
        
        return data.map((item) => {
            const index = item.title.indexOf(searchValue);
            const beforeStr = item.title.substr(0, index);
            const afterStr = item.title.substr(index + searchValue.length);
            const title =
                index > -1 ? (
                    <span>
                        {beforeStr}
                        <span style={{ color: "red" }}>{searchValue}</span>
                        {afterStr}
                    </span>
                ) : (
                    <span>{item.title}</span>
                );
            if (item.children && item.children.length > 0) {
                //className={searchTreeKey.indexOf(item.key) > -1 ? styles.yes : styles.no}
                return <TreeNode title={title} key={item.key} >
                    {
                        renderTreeNode(item.children)
                    }
                </TreeNode>
            }
            return <TreeNode key={item.key} title={title}  ></TreeNode>
        })
    }
    const expandedKeysFn = () => {
        let arr = [];
        let loop = (data) => {
            data.map((item, index) => {
                arr.push(item.key);
                if (item.children && item.children.length > 0) {
                    loop(item.children)
                }
            })
        }
        loop(data);
        setExpandedKeys(arr);
       
    }
   const onExpand = expandedKeys => {
        console.log('onExpand', expandedKeys);
        setExpandedKeys(expandedKeys);
        setAutoExpandParent(false);
    };
   const onCheck = (checkedKeys) => {
        setCheckedKeys(checkedKeys);
    }

    return (
        <div>
            <Search style={{ marginBottom: 8 }} placeholder="Search" onChange={onChange} />
            <Tree
                checkable
                expandedKeys={expandedKeys} //默认展开的key
                onExpand={onExpand} //展开事件
                autoExpandParent={autoExpandParent} //是否自动展开父节点
                checkedKeys={checkedKeys} //选中的key
                onCheck={onCheck} //选中事件
            >
                {renderTreeNode(data)}
            </Tree>
        </div>
    )
}

export default Index



 

 数据量大造成的卡顿

可以给Tree加一个height属性:使用 height 属性则切换为虚拟滚动。

<Tree height={500}/>

这样可以缓解卡顿现象

antd tree虚拟滚动

总结:

 如果想要antd-tree组件带搜索框的使用及踩坑(只保留搜索的内容并且标红)可以看这篇

 我自己实现的Tree带搜索antd Tree 组件 带搜索 

如果想要react-antd Tree(树形组件)默认展开和选中踩坑及使用可以看这篇

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论
antd-datepicker是Ant Design提供的日期选择器组件,可用于选择日期和时间值。获取时间值的方式有以下几种: 1. 使用onChange事件:在DatePicker组件上绑定onChange事件,当用户选择了日期或时间时,会触发该事件并将选择的时间值作为参数传递给回调函数。可以通过e.target.value来获取选择的时间值。 ```jsx <DatePicker onChange={handleDateChange} /> ``` ```jsx const handleDateChange = (value) => { console.log(value); // 可以对选择的时间值进行相关处理 } ``` 2. 使用moment.js库:Ant Design的DatePicker组件默认返回的是Moment.js对象,可以使用该库提供的方法来获取和处理时间值。 ```jsx import moment from 'moment'; <DatePicker onChange={handleDateChange} /> ``` ```jsx const handleDateChange = (value) => { const selectedValue = moment(value).format('YYYY-MM-DD'); console.log(selectedValue); // 可以对选择的时间值进行相关处理 } ``` 相关设置方式包括: 1. 默认时间值:可以通过设置defaultValue属性来指定DatePicker组件的默认时间值。 ```jsx <DatePicker defaultValue={moment('2022-01-01', 'YYYY-MM-DD')} /> ``` 2. 可选时间范围:可以通过设置disabledDate属性来限制可选的时间范围。该属性接收一个函数,根据函数的返回值来控制禁用的日期。 ```jsx <DatePicker disabledDate={disabledDate} /> ``` ```jsx const disabledDate = (current) => { // 返回true表示禁用该日期 return current && current < moment().endOf('day'); } ``` 3. 时间格式:可以通过设置format属性来指定DatePicker组件的时间格式。 ```jsx <DatePicker format="YYYY-MM-DD HH:mm:ss" /> ``` 以上就是antd-datepicker组件获取时间值及相关设置方式的介绍。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

崽崽的谷雨

漫漫前端路,摸爬滚打

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值