數據數據結構
var data = [ { "area_id": 5, "name": "廣東省", "parent_id": 0, }, { "area_id": 6, "name": "廣州市", "parent_id": 5, }, { "area_id": 7, "name": "深圳市", "parent_id": 5, }, { "area_id": 4, "name": "北京市", "parent_id": 3, }, { "area_id": 3, "name": "北京", "parent_id": 0, }, { "area_id": 2, "name": "測試子地區", "parent_id": 1, }, { "area_id": 1, "name": "測試地區", "parent_id": 0, } ]
function toTreeData(data,pid){ function tree(id){ let arr = [] data.filter(item =>{ return item.parent_id ==id }).forEach(item => { arr.push({ area_id: item.area_id, label:item.name, children: tree(item.area_id) }) }) return arr } return tree(pid)// 第一級節點的父id,是null或者0,視狀況傳入 }
不過,該方法有個缺點,在我使用組件的時候須要的數據結構中,若是子級沒有數據children返回[]。
須要將數據整理樹形結構的主要在菜單欄或分類的樹形結構上,固然還有像省市這種有從屬關係的結構。測試
function setTreeData(arr){ // 刪除全部的children,以防止屢次調用 arr.forEach(function(item){ delete item.children }); let map = {};//構建map arr.forEach(i=>{ map[i.area_id]=i; //構建以area_id爲鍵 當前數據爲值 }); let treeData = []; arr.forEach(child => { const mapItem = map[child.parent_id];//判斷當前數據的parent_id是否存在map中 if(mapItem){//存在則表示當前數據不是最頂層的數據 //注意: 這裏的map中的數據是引用了arr的它的指向仍是arr,當mapItem改變時arr也會改變,踩坑點 (mapItem.children || (mapItem.children = [])).push(child);//這裏判斷mapItem中是否存在child }else {//不存在則是頂層數據 treeData.push(child) } }) return treeData } console.log(setTreeData(data))
這種方法有一種容易犯錯的地方,就是它會改變原數據,我就在這裏踩了很久的坑,因此一開始採用了刪除children的初始化了一遍。spa
參考:一位大佬的code