当前位置: 首页>前端>正文

antdesign列表搜索方法 antd搜索框

前言:

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

一、预期的效果

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

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

antdesign列表搜索方法 antd搜索框,antdesign列表搜索方法 antd搜索框_antdesign列表搜索方法,第1张

二、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虚拟滚动


https://www.xamrdz.com/web/2kq1939889.html

相关文章: