- 組件定義
子組件:
- 以下內容為普通扁平化格式轉換成樹形對象的方法
- 其中list的格式為
-
[
{
"id": 100,
"pId": 0,
"name": "科技",
"title": "科技",
"checked": false,
"open": false,
"nocheck": false
},
{
"id": 101,
"pId": 100,
"name": "深圳總公司",
"title": "深圳總公司",
"checked": false,
"open": false,
"nocheck": false
},
{
"id": 102,
"pId": 100,
"name": "長沙分公司",
"title": "長沙分公司",
"checked": false,
"open": false,
"nocheck": false
},
{
"id": 103,
"pId": 101,
"name": "研發部門",
"title": "研發部門",
"checked": false,
"open": false,
"nocheck": false
},
{
"id": 104,
"pId": 101,
"name": "市場部門",
"title": "市場部門",
"checked": false,
"open": false,
"nocheck": false
},
{
"id": 105,
"pId": 101,
"name": "測試部門",
"title": "測試部門",
"checked": false,
"open": false,
"nocheck": false
},
{
"id": 106,
"pId": 101,
"name": "財務部門",
"title": "財務部門",
"checked": false,
"open": false,
"nocheck": false
},
{
"id": 107,
"pId": 101,
"name": "運維部門",
"title": "運維部門",
"checked": false,
"open": false,
"nocheck": false
},
{
"id": 108,
"pId": 102,
"name": "市場部門",
"title": "市場部門",
"checked": false,
"open": false,
"nocheck": false
},
{
"id": 109,
"pId": 102,
"name": "財務部門",
"title": "財務部門",
"checked": false,
"open": false,
"nocheck": false
}
] -
buildTree(list){let pidStr = 'pId';let idStr = 'id';let childrenStr = 'children';
let listOjb = {}; // 用來儲存{key: obj}格式的對象let treeList = []; // 用來儲存最終樹形結構數據的數組
// 將數據變換成{key: obj}格式,方便下面處理數據for (let i = 0; i < list.length; i++) {listOjb[list[i][idStr]] = list[i]}
for (let j = 0; j < list.length; j++) {// 判斷父級是否存在let haveParent = listOjb[list[j][pidStr]]if (haveParent) {// 如果有沒有父級children字段,就創建一個children字段!haveParent[childrenStr] && (haveParent[childrenStr] = [])// 在父級里插入子項haveParent[childrenStr].push(list[j])} else {// 如果沒有父級直接插入到最外層treeList.push(list[j])}}return treeList},
實現算法buildTree
算法思想:
先將數組中的每一個節點放到temp對象中(創建map)
即數組中有{id: '2-3', parent_id: '2',...}這樣一個節點,需要將他放到temp中變成 '2-3': {id: '2-3', parent_id: '2',...}這種JSON結構
直接遍歷整個temp對象,通過這句代碼 temp[temp[i].parent_id].children[temp[i].id] = temp[i]; 將當前子節點與父節點建立連接。是因為我們保證了父節點一定在子節點前,那么當子節點出現的時候就直接可以用temp[temp[i].parent_id]來查找到父節點這個時候先父節點的children對象中添加一個引用即可。
/**
* 將一維的扁平數組轉換為多層級對象
* @param {[type]} list 一維數組,數組中每一個元素需包含id和parent_id兩個屬性
* @return {[type]} tree 多層級樹狀結構
*/
function buildTree(list){
let temp = {};
let tree = {};
for(let i in list){
temp[list[i].id] = list[i];
}
for(let i in temp){
if(temp[i].parent_id) {
if(!temp[temp[i].parent_id].children) {
temp[temp[i].parent_id].children = new Object();
}
temp[temp[i].parent_id].children[temp[i].id] = temp[i];
} else {
tree[temp[i].id] = temp[i];
}
}
return tree;
}
測試結果:
可以看到函數成功地構建了多級的樹狀結構
這個算法的效率是極高的,比多重for循環來的好得多。
以下是測試數據,用時只需5毫秒左右:
var menu_list = [{
id: '1',
menu_name: '設置',
menu_url: 'setting',
parent_id: 0
}, {
id: '1-1',
menu_name: '權限設置',
menu_url: 'setting.permission',
parent_id: '1'
}, {
id: '1-1-1',
menu_name: '用戶管理列表',
menu_url: 'setting.permission.user_list',
parent_id: '1-1'
}, {
id: '1-1-2',
menu_name: '用戶管理新增',
menu_url: 'setting.permission.user_add',
parent_id: '1-1'
}, {
id: '1-1-3',
menu_name: '角色管理列表',
menu_url: 'setting.permission.role_list',
parent_id: '1-1'
}, {
id: '1-1-4',
menu_name: '角色管理新增',
menu_url: 'setting.permission.role_add',
parent_id: '1-1'
}, {
id: '1-2',
menu_name: '菜單設置',
menu_url: 'setting.menu',
parent_id: '1'
}, {
id: '1-2-1',
menu_name: '菜單列表',
menu_url: 'setting.menu.menu_list',
parent_id: '1-2'
}, {
id: '1-2-2',
menu_name: '菜單添加',
menu_url: 'setting.menu.menu_add',
parent_id: '1-2'
}, {
id: '2',
menu_name: '訂單',
menu_url: 'order',
parent_id: 0
}, {
id: '2-1',
menu_name: '報單審核',
menu_url: 'order.orderreview',
parent_id: '2'
}, {
id: '2-2',
menu_name: '退款管理',
menu_url: 'order.refundmanagement',
parent_id: '2'
}, {
id: '2-3',
menu_name: '實物訂單',
menu_url: 'order.realorder',
parent_id: '2'
}, {
id: '2-1-1',
menu_name: '全部報單',
menu_url: 'order.orderreview.all',
parent_id: '2-1'
}, {
id: '2-2-1',
menu_name: '所有記錄',
menu_url: 'order.refundmanagement.all',
parent_id: '2-2'
}, {
id: '2-2-2',
menu_name: '待處理',
menu_url: 'order.refundmanagement.wait',
parent_id: '2-2'
}, {
id: '2-2-3',
menu_name: '退款原因',
menu_url: 'order.refundmanagement.result',
parent_id: '2-2'
}, {
id: '2-3-1',
menu_name: '實物訂單管理',
menu_url: 'order.realorder.list',
parent_id: '2-3'
}, {
id: '3',
menu_name: '商品',
menu_url: 'commodity',
parent_id: 0
}, {
id: '3-1',
menu_name: '分類管理',
menu_url: 'commodity.classifieldmanagement',
parent_id: '3'
}, {
id: '3-1-1',
menu_name: '管理',
menu_url: 'commodity.classifieldmanagement.management',
parent_id: '3-1'
}, {
id: '3-1-2',
menu_name: '編輯或新增',
menu_url: 'commodity.classifieldmanagement.edit',
parent_id: '3-1'
}, {
id: '3-2',
menu_name: '品牌管理',
menu_url: 'commodity.brandmanagement',
parent_id: '3'
}, {
id: '3-2-1',
menu_name: '管理',
menu_url: 'commodity.brandmanagement.management',
parent_id: '3-2'
}, {
id: '3-2-2',
menu_name: '編輯或新增',
menu_url: 'commodity.brandmanagement.edit',
parent_id: '3-2'
}, {
id: '3-3',
menu_name: '商品管理',
menu_url: 'commodity.commoditymanagement',
parent_id: '3'
}, {
id: '3-3-1',
menu_name: '管理',
menu_url: 'commodity.commoditymanagement.management',
parent_id: '3-3'
}, {
id: '3-3-2',
menu_name: '編輯或新增',
menu_url: 'commodity.commoditymanagement.edit',
parent_id: '3-3'
}, {
id: '3-4',
menu_name: '類型管理',
menu_url: 'commodity.typeManagement',
parent_id: '3'
}, {
id: '3-4-1',
menu_name: '管理',
menu_url: 'commodity.typeManagement.management',
parent_id: '3-4'
}, {
id: '3-4-2',
menu_name: '編輯或新增',
menu_url: 'commodity.typeManagement.edit',
parent_id: '3-4'
}]