先来解释下广度和深度的意思:
所谓广度,就是一层一层的,向下遍历,层层堵截,看下面这幅图

度优先遍历:对每一个可能的分支路径深入到不能再深入为止,而且每个结点只能访问一次。不全部保留结点,占用空间少;有回溯操作(即有入栈、出栈操作),运行速度慢

接下来上代码:
// 模拟数据
let msg = [
{
name: 1,
children: [
{
name: "1-1",
children: [
{
name: "1-1-1",
},
{
name: "1-1-2",
},
],
},
],
},
{
name: 2,
children: [
{
name: "2-1",
},
{
name: "2-2",
},
],
},
];
// 广度优先
function wideTraversal(msg, data = []) {
// console.log(msg.length);
let nowData = [];
if (msg != null) {
for (let i = 0; i < msg.length; i++) {
// console.log(i);
data.push(msg[i]);
msg[i].children && nowData.push(...msg[i].children);
if (msg.length == i + 1) {
// 确保第一层遍历完
wideTraversal(nowData, data);
}
// msg.length == i + 1 && wideTraversal(nowData, data);
}
}
return data;
}
let data = wideTraversal(msg);
console.log(data);
//深度优先遍历
function deepTraversal(msg, data = []) {
if (msg != null) {
for (let i = 0; i < msg.length; i++) {
data.push(msg[i]);
msg[i].children && deepTraversal(msg[i].children, data);
}
}
return data;
}
let data = deepTraversal(msg);
console.log(data);上面代码的打印结果的tree 其实就是树结构的渲染顺序 需要这么理解。
react版本简单的递归例子:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<script src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/babel-standalone@6.26.0/babel.js"></script>
</head>
<body>
<div id="root"></div>
</body>
<script type="text/babel">
function Testr() {
return <h1>123</h1>;
}
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
testVal: "123",
tree: [
{
label: "dashboard",
key: "dashboard",
children: [
{
label: "User Dashboard",
children: [
{
label: "xxxx",
key: "xxxx",
},
{
label: "yyyy",
key: "yyyy",
},
],
},
{
label: "Onboarding Dashboard",
key: "OnboardingDashboard",
},
],
},
{
label: "Timesheets/Expenses",
key: "Timesheets",
children: [
{
label: "User Timesheets",
children: [
{
label: "ss",
key: "ss",
},
{
label: "qq",
key: "qq",
},
],
},
{
label: "Onboarding Timesheets",
key: "OnboardingTimesheets",
},
],
},
],
};
}
getMenuNodes = (menuList) => {
return menuList.map((item) => {
if (!item.children) {
return (
<li style={{ paddingLeft: 25 }}>
<span>{item.label}</span>
</li>
);
} else {
return (
<li style={{ paddingLeft: 25 }} key={item.key}>
<span>{item.label}</span>
{this.getMenuNodes(item.children)}
</li>
);
}
});
};
render() {
const { tree } = this.state;
return <div>{this.getMenuNodes(tree)}</div>;
}
}
ReactDOM.render(<App />, document.getElementById("root"));
</script>
</html>给一个树结构 递归添加一个自定义字段:
举例:
{
id: 'root',
name: 'Parent',
children: [
{
id: '1',
name: 'Child - 1',
},
],
},
],
},转为:
{
id: 'root',
name: 'Parent',
checked:false ,
children: [
{
id: '1',
name: 'Child - 1',
checked:false
},
],
},
],
},下面是代码:
const setTreeCheckedVal = (treeData) => {
for (let i = 0; i < treeData.length; i++) {
treeData[i].checked = false;
treeData[i].children && this.setTreeCheckedVal(treeData[i].children);
}
return treeData;
};
let data2 = this.setTreeCheckedVal(RadioTreeData);
console.log(data2);