天天看點

antd react拿到樹結構選中的資料,樹結構多層穿梭框(上)

效果大概如下,可以自己拿代碼試試,這個現在是隻能拿到選中的添加到右邊,并且會覆寫右邊的資料,再研究下追加到右邊,有需要的可以自己再封裝成通用元件

樹結構穿梭框下篇,可追加資料

antd react拿到樹結構選中的資料,樹結構多層穿梭框(上)
import React, { Component } from 'react';
import { Tree, Input, Button } from 'antd';
// import requset from '@/utils/request';
import { NuCard } from '@cbay/cbay-ui';
import { cloneDeep } from 'lodash';
const { Search } = Input;
//扁平後資料
let arr = [];
class TransferTree extends Component {
    state = {
        treeData: [],
        expandedKeys: [],
        searchValue: '',
        autoExpandParent: true,
        loading: false,
        rightTree: [],
        rightTreeCopy: [],
        checkedKeysLeft: [],
        leftBtnDisabled: true,
        rightBtnDisabled: true
    };

    componentDidMount() {
        //請求樹結構
        //如果沒有給父節點key,那就給每個子節點設定父節點key
        const newDATA = cloneDeep(DATA);
        this.setParent(newDATA);
        // console.log(DATA);
        //扁平資料
        this.setnode(newDATA);
        // console.log(arr);
    }

    //1設定父節點id
    setParent = treeData => {
        treeData.map(t => {
            if (t.children && t.children.length) {
                t.children.map(c => {
                    c.parentKey = t.key;
                });
                this.setParent(t.children);
            } else {
                return;
            }
        });
    };
    //2扁平資料
    setnode = c => {
        c.map(item => {
            arr.push(item);
            item.children && this.setnode(item.children);
        });
    };

    onSelect = (selectedKeys, info) => {
        console.log(info);
        const { type, eventKey } = info.node.props;
        this.setState({
            selected: {
                type,
                id: eventKey
            }
        });
    };

    checked = (checkedkeys, node) => {
        const { halfCheckedKeys } = node || {};
        //設定左邊複選框選中的key
        this.setState({
            checkedKeysLeft: {
                checked: checkedkeys,
                halfChecked: halfCheckedKeys
            }
        });
        //
        let checkedAllLeftKey = checkedkeys.concat(halfCheckedKeys);

        // const rightTreeCopy = this.ListToTree(selectValue);
        const rightTreeCopy = this.ListToTree(checkedAllLeftKey);
        this.setState({
            rightTreeCopy,
            checkedAllLeftKey,
            leftBtnDisabled: !checkedkeys.length
        });
        // console.log(rightTreeCopy);
    };

    checkedRight = checkedkeys => {
        const { checkedAllLeftKey } = this.state;
        let checkAllCopy = cloneDeep(checkedAllLeftKey);

        checkedkeys.forEach(item => {
            let index = checkAllCopy.findIndex(c => {
                return item === c;
            });
            checkAllCopy.splice(index, 1);
        });
        //左邊删除右邊選中後的key
        this.setState({
            checkAllCopy,
            rightBtnDisabled: !checkedkeys.length
        });
    };

    //5.把選中的扁平的資料變成樹結構
    ListToTree(checkedAllKey) {
        //3,防止循環插入重複資料,把children設定null
        arr.map(item => {
            if (item.children) {
                item.children = null;
            }

            return item;
        });
        //4.在扁平後的資料中篩選出選中的資料
        let selectValue = checkedAllKey.map(item => {
            return arr.find(a => {
                return item == a.key;
            });
        });
        let copyList = cloneDeep(selectValue);
        // console.log(copyList);

        copyList.forEach(ele => {
            // 第一次forEach周遊到所有的數組對象,不做去重,數組依舊擁有6個元素
            let parentId = ele.parentKey;
            if (!parentId) {
                //是根元素的話 ,不做任何操作.
            } else {
                //如果ele是子元素的話 ,把ele扔到他的父親的child數組中.它的父元素也可能是别人的子元素

                copyList.forEach(d => {
                    if (d.key === parentId) {
                        let childArray = d.children;
                        // 一則避免了去給d.child聲明定義空數組
                        // childArray為undefined時,用push方法去報undefined.push的錯
                        if (!childArray) {
                            childArray = [];
                        }
                        // 用push保證同級别的對象有序追加
                        childArray.push(ele);
                        d.children = childArray;
                    } //else的地方不做處理,保證了最深層的對象沒有child屬性
                });
            }
        });
        //去除重複元素
        copyList = copyList.filter(ele => !ele.parentKey);

        return copyList;
    }

    //把選中的資料設定到右邊
    toRight = () => {
        const { rightTreeCopy } = this.state;
        this.setState({
            rightTree: rightTreeCopy,
            checkedKeysLeft: {
                checked: [],
                halfChecked: []
            },
            leftBtnDisabled: true,
            rightBtnDisabled: true
        });
    };
    //取消右邊的資料
    toLeft = () => {
        const { checkAllCopy, checkedKeysLeft } = this.state;
        //console.log(checkAllCopy, checkedKeysLeft);
        const rightTreeCopy = this.ListToTree(checkAllCopy);
        this.setState({
            rightTree: rightTreeCopy,
            checkedAllLeftKey: checkAllCopy,
            checkedKeysLeft: {
                checked: [],
                halfChecked: []
            },
            leftBtnDisabled: true,
            rightBtnDisabled: true
        });
    };

    onExpand = expandedKeys => {
        this.setState({
            expandedKeys,
            autoExpandParent: false
        });
    };

    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 (this.getParentKey(key, node.children)) {
                    parentKey = this.getParentKey(key, node.children);
                }
            }
        }
        return parentKey;
    };

    //搜尋
    onChange = e => {
        const { value } = e.target;

        const newarr = cloneDeep(arr);
        const newDATA = cloneDeep(DATA);
        const expandedKeys = newarr
            .map(item => {
                if (item.title.indexOf(value) > -1) {
                    return this.getParentKey(item.key, newDATA);
                }
                return null;
            })
            .filter((item, i, self) => item && self.indexOf(item) === i);

        this.setState({
            expandedKeys,
            searchValue: value,
            autoExpandParent: true
        });
    };
    loop = data =>
        data.map(item => {
        //拼接
            const index = item.title.indexOf(this.state.searchValue);
            const beforeStr = item.title.substr(0, index);
            const afterStr = item.title.substr(
                index + this.state.searchValue.length
            );
            const title =
                index > -1 ? (
                    <span>
                        {beforeStr}
                        <span style={{ color: 'red' }}>
                            {this.state.searchValue}
                        </span>
                        {afterStr}
                    </span>
                ) : (
                    <span>{item.title}</span>
                );
            if (item.children) {
                return {
                    title,
                    key: item.key,
                    children: this.loop(item.children)
                };
            }

            return {
                title,
                key: item.key
            };
        });
    render() {
        const {
            loading,
            expandedKeys,
            autoExpandParent,
            checkedKeysLeft
        } = this.state;

        return (
            <div style={{ display: 'flex' }}>
                <div style={{ width: '50%' }}>
                    <Search
                        style={{ marginBottom: 8 }}
                        placeholder="Search"
                        onChange={this.onChange}
                    />
                    <NuCard loading={loading}>
                        <Tree
                            showLine
                            checkable
                            checkStrictly={false}
                            onCheck={this.checked}
                            onExpand={this.onExpand}
                            //checkedKeys={checkedKeysLeft}左邊選中的key
                            expandedKeys={expandedKeys}
                            autoExpandParent={autoExpandParent}
                            // onSelect={this.onSelect}
                            treeData={this.loop(cloneDeep(DATA))}
                        >
                            {/* {this.renderTreeNode()} */}
                        </Tree>
                    </NuCard>
                </div>
                <Button
                    onClick={this.toRight}
                    disabled={this.state.leftBtnDisabled}
                >
                    toRight
                </Button>
                <Button
                    onClick={this.toLeft}
                    disabled={this.state.rightBtnDisabled}
                >
                    toLeft
                </Button>

                <div style={{ width: '50%' }}>
                    <NuCard loading={loading}>
                        <Tree
                            showLine
                            checkable
                            checkStrictly={false}
                            onCheck={this.checkedRight}
                            // onSelect={this.onSelect}
                            treeData={this.state.rightTree}
                        >
                            {/* {this.renderTreeNodeCopy()} */}
                        </Tree>
                    </NuCard>
                </div>
            </div>
        );
    }
}

export default TransferTree;

const DATA = [
    {
        title: '一級1',
        key: 1,
        field: 'name1',
        checked: true,
        spread: true,
        children: [
            {
                title: '二級1-1 ',
                key: 3,
                field: 'name11',
                children: [
                    {
                        title: '三級1-1-3',
                        key: 23,
                        field: '',
                        children: [
                            {
                                title: '四級1-1-3-1',
                                key: 24,
                                field: '',
                                children: [
                                    {
                                        title: '五級1-1-3-1-1',
                                        key: 30,
                                        field: ''
                                    },
                                    {
                                        title: '五級1-1-3-1-2',
                                        key: 31,
                                        field: ''
                                    }
                                ]
                            }
                        ]
                    },
                    {
                        title: '三級1-1-1',
                        key: 7,
                        field: '',
                        children: [
                            {
                                title: '四級1-1-1-1 ',
                                key: 15,
                                field: ''
                            }
                        ]
                    },
                    {
                        title: '三級1-1-2',
                        key: 8,
                        field: '',
                        children: [
                            {
                                title: '四級1-1-2-1',
                                key: 32,
                                field: ''
                            }
                        ]
                    }
                ]
            },
            {
                title: '二級1-2',
                key: 4,
                spread: true,
                children: [
                    {
                        title: '三級1-2-1',
                        key: 9,
                        field: ''
                    },
                    {
                        title: '三級1-2-2',
                        key: 10,
                        field: ''
                    }
                ]
            },
            {
                title: '二級1-3',
                key: 20,
                field: '',
                children: [
                    {
                        title: '三級1-3-1',
                        key: 21,
                        field: ''
                    },
                    {
                        title: '三級1-3-2',
                        key: 22,
                        field: ''
                    }
                ]
            }
        ]
    },
    {
        title: '一級2',
        key: 2,
        field: '',
        spread: true,
        children: [
            {
                title: '二級2-1',
                key: 5,
                field: '',
                spread: true,
                children: [
                    {
                        title: '三級2-1-1',
                        key: 11,
                        field: ''
                    },
                    {
                        title: '三級2-1-2',
                        key: 12,
                        field: ''
                    }
                ]
            },
            {
                title: '二級2-2',
                key: 6,
                field: '',
                children: [
                    {
                        title: '三級2-2-1',
                        key: 13,
                        field: ''
                    },
                    {
                        title: '三級2-2-2',
                        key: 14,
                        field: ''
                    }
                ]
            }
        ]
    },
    {
        title: '一級3',
        key: 16,
        field: '',
        children: [
            {
                title: '二級3-1',
                key: 17,
                field: '',
                fixed: true,
                children: [
                    {
                        title: '三級3-1-1',
                        key: 18,
                        field: ''
                    },
                    {
                        title: '三級3-1-2',
                        key: 19,
                        field: ''
                    }
                ]
            },
            {
                title: '二級3-2',
                key: 27,
                field: '',
                children: [
                    {
                        title: '三級3-2-1',
                        key: 28,
                        field: ''
                    },
                    {
                        title: '三級3-2-2',
                        key: 29,
                        field: ''
                    }
                ]
            }
        ]
    }
];
           

繼續閱讀