1. 程式人生 > >react+antd實現樹形選單展示(後臺使用java)

react+antd實現樹形選單展示(後臺使用java)

1.資料庫表設計(我使用的是單表一對多,裡面需要有一個pid指向父層級的id)
這就是表基本結構
2.在後臺獲取資料的時候,使用的實體類為此種形式

public class UserTree {
    private Integer id;
    private String name;
    private Integer pid;
    //每個實體類物件中都有持有本類物件的集合
    private List<UserTree> childrenList;

省略get,set方法
}
通過此種方式傳遞到前臺的json資料格式化為
[{
	id: 'xx',
	name: 'xx',
	pid: 'xx',
	childrenList: [{
		id: 'xx',
		name: 'xx',
		pid: 'xx',
		childrenList: [{ ......}]
	}]
}]

3.如何深遞迴遍歷資料

/**
  * 查詢樹選單,深遞迴
  */
  傳入的id值為pid的值,在外部呼叫時,第一次傳入的為父層級的pid值,也就是0
    public List<UserTree> searchUserTreeById(Integer id) {
        //1.得到所有的父節點集合
        List<UserTree> userTrees = reactMapper.searchUserTreeById(id);
        //2.判斷父節點下面還有沒有子節點
       if(userTrees!=null && userTrees.size()!=0){
       //3.遍歷所有的父節點集合,根據父節點id查詢資料庫獲得所有該父節點下所有的子節點
           for (UserTree userTree : userTrees) {
               List<UserTree> userTrees1 = searchUserTreeById(userTree.getId());
               userTree.setChildrenList(userTrees1);
           }
       }
        return userTrees;
    }

4.sql語句怎麼寫

Mapper介面寫法,傳入當前物件的id值即可
public List<UserTree> searchUserTreeByPid(Integer id);
sql語句比較簡單,在Mapper檔案中使用此語句即可
<select id="searchUserTreeById" resultType="com.yibuqiche.user.pojo.UserTree">
        SELECT id,name,pid FROM user_tree WHERE pid=#{id}
</select>

5.在前臺需要做遞迴遍歷資料,直接上程式碼,我使用的是修飾器語法,所有資料請求都在store中進行

import React from 'react'
import { Tree ,Menu} from 'antd';
import {inject, observer} from 'mobx-react'
import demoStore from '../store'

const DirectoryTree = Tree.DirectoryTree;
const TreeNode = Tree.TreeNode;
const SubMenu = Menu.SubMenu;




@inject("demoStore") @observer
class UserTree extends React.Component{
    
    //遞迴方法遍歷選單
    recursion=(dataSource)=>{
        return (
            dataSource.map((menu, index) => {
                if (menu.childrenList) {
                    return (
                        <SubMenu key={menu.id} title={menu.name}>
                            {this.recursion(menu.childrenList)}
                        </SubMenu>
                    )
                } else {
                    return (<Menu.Item key={menu.id}>{menu.name}</Menu.Item>)
                }
            })
        )
    }
    
    //遞迴方法遍歷樹形控制元件
    renderTree = (data,idx) =>{
        console.log('樹形選單資料來源', data);
        return data.map(item => {
            if (!item.childrenList) {
                return (
                    <TreeNode title={item.name} key={item.id} />
                )
            } else {
                return (
                    <TreeNode title={item.name} key={item.id}>
                        {this.renderTree(item.childrenList)}
                    </TreeNode>
                )
            }
        })

    };

    // renderTreeNodes(data) {
    //     return data.map((item) => {
    //         if (item.childrenList) {
    //             return (
    //                 <TreeNode title={item.name} key={item.id} dataRef={item}>
    //                     {this.renderTreeNodes(item.childrenList)}
    //                 </TreeNode>
    //             );
    //         }
    //         return <TreeNode {...item} title={item.name} dataRef={item} />;
    //     });
    // }
    
    //頁面載入呼叫
    componentDidMount(){
        this.props.demoStore.selectParentId(0);
    }

    render(){
        const {DataSource,treeList} = this.props.demoStore
        // const treeElement = this.renderTree(treeList);
        // console.log(this.props.demoStore.tree[0].name,"1111111")
        return(
            <div>
                {/*返回樹結構*/}
                <DirectoryTree
                    multiple
                    defaultExpandAll
                    onSelect={this.onSelect}
                    onExpand={this.onExpand}
                >
                    {/*呼叫上面的遞迴方法*/}
                    {this.renderTree(treeList)}
                </DirectoryTree>
                
                {/*返回選單結構*/}
                <Menu
                    onClick={this.handleClick}
                    style={{ width: 256 }}
                    defaultSelectedKeys={['1']}
                    defaultOpenKeys={['sub1']}
                    mode="inline"
                >
                    {/*呼叫上面的遞迴方法*/}
                    {this.recursion(treeList)}
                </Menu>
                
            </div>
        )
    }

    
}
export default UserTree

這是樹形控制元件的請求,寫在store中,

  //樹形控制元件
    selectParentId= async (id)=>{
        const tree = await json.get("http://localhost:8080/Request:selectTree/"+id);
        //改變觀察者模式的值必須在runInAction方法中改變
        runInAction(()=>{
                // this.tree = tree;
                this.treeList = Array.isArray(tree) ? tree :[]
        })
    }

至此:樹結構以及可以在前臺顯示了,效果如下,可以無限深遞迴
在這裡插入圖片描述在這裡插入圖片描述