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: [{ ......}]
}]
}]
如何深递归遍历数据
/**
* 查询树菜单,深递归
*/
传入的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 :[]
})
}
至此:树结构以及可以在前台显示了,效果如下,可以无限深递归