js递归获取数组节点数据

js递归获取数组节点数据

需求:根据后端返回的树形数据对数据进行解析,取到符合要求的节点数据并返回

树形数据leftMenuList

[
	{
		"id": "4c74f6018de1448fa7748171b96833eb",		
		"createDate": "2020-08-05 15:52:45",
		"updateDate": "2021-12-21 15:25:06",
		"parentIds": "0,1,",
		"name": "首页",
		"sort": 50,
		"children": [],
		"childNum": 0,
		"href": "/home",
		"icon": "el-icon-house",
		"isShow": "1",
		"type": "1",
		"plateType": "0",
		"backgroundType": "1",
		"parentId": "1"
	},{
		"id": "27",
		"createDate": "2013-05-27 08:00:00",
		"updateDate": "2021-12-21 15:24:47",
		"parentIds": "0,1,",
		"name": "个人中心",
		"sort": 170,
		"children": [
			{
				"id": "95a6a82dc5fc4d07b46e5df57a0606a3",
				"createDate": "2015-11-14 11:14:30",
				"updateDate": "2021-12-21 14:50:05",
				"parentIds": "0,1,27,",
				"name": "我的信箱",
				"sort": 30,
				"children": [],
				"childNum": 0,
				"href": "/mailbox/index",
				"icon": "fa fa-envelope",
				"isShow": "1",
				"type": "1",
				"plateType": "3",
				"backgroundType": "1",
				"parentId": "27"
			},
			{
				"id": "29",
				"createDate": "2013-05-27 08:00:00",
				"updateDate": "2021-12-21 15:13:49",
				"parentIds": "0,1,27,",
				"name": "个人信息",
				"sort": 90,
				"children": [],
				"childNum": 0,
				"href": "/sys/user/UserInfo",
				"icon": "fa fa-blind",
				"isShow": "1",
				"type": "1",
				"plateType": "3",
				"backgroundType": "1",
				"parentId": "27"
			}	
		],
		"childNum": 6,
		"icon": "fa fa-user-secret",
		"isShow": "1",
		"type": "1",
		"permission": "sys:personal:center",
		"plateType": "3",
		"backgroundType": "1",
		"parentId": "1"
	}
}

实现逻辑:
判断leftMenuList树形数据节点属性href值与给定值是否相同,如果相同就返回对应节点的数据

最开始用filter过滤数组并递归,实现代码如下:

menuListFilter (arr, name) {
 return arr.filter(item => {
          if(item.href === tab.name) {return true}
          if(item.children.length>0){
          return this.menuListFilter(item.children, tab)}
          })
}
let currentMenu = this.menuListFilter(this.leftMenuList, tab.name)

但是发现只能返回首层的数据,递归到第二层就无法返回了,

于是转换思路,直接循环数组并递归,并设置一个中间变量,临时存取结果,判断变量中有值就直接结束函数并返回,最后再返回一下menu,防止什么都取到不到的情况,实现代码如下:

menuListFilter (arr, name) {
        // debugger
        let menu = []
        for(let i=0; i<arr.length; i++){
          if(arr[i].href === name) {menu = arr[i]}
          if(!menu&&arr[i].children.length>0){
            menu = this.menuListFilter(arr[i].children, name)
          }
          if(menu) {return menu}  //判断变量中有值就直接结束函数并返回
        }
        return menu
}
let currentMenu = this.menuListFilter(this.leftMenuList, tab.name

这样写完后运行,发现始终返回的是空数组[],然后设置debugger打断点调试,逐行运行,才发现menu的判断值弄错了,在网上一搜才发现空数组[]的布尔值为true,然后修改了一下代码,判断menu.length的值,再次运行,正确实现了功能逻辑。
最后思考一下,既然for循环可以,forEach循环肯定也可以了,于是又优化了一下代码,最终实现代码如下:

 menuListFilter (arr, name) {
        let menu = []
        arr.forEach(item => {
          if(item.href === name) {menu = item}
          if(menu.length==0&&item.children.length>0){
            menu = this.menuListFilter(item.children, name)
          }
          if(menu.length>0) {return menu}
        })
        return menu
}
let currentMenu = this.menuListFilter(this.leftMenuList, tab.name)
上一篇:Element Ui 导航菜单封装


下一篇:vue如何引入外部的js文件