js實現無限層級樹形資料結構(創新演算法)
阿新 • • 發佈:2020-02-28
由於做專案的需要,把一個線性陣列轉成樹形陣列,在網上查了很多文章,覺得他們寫的太複雜了,於是自己寫了一個,在折騰了一下午終於把它寫出來啦(激動.gif),用兩個filter過濾器就搞定了,程式碼簡潔明瞭,資料結構小白都能看懂。
js程式碼:把扁平資料轉成樹形資料
function setTreeData(source){ let cloneData = JSON.parse(JSON.stringify(source)) // 對源資料深度克隆 return cloneData.filter(father=>{ // 迴圈所有項,並新增children屬性 let branchArr = cloneData.filter(child=> father.id == child.parentId); // 返回每一項的子級陣列 branchArr.length>0 ? father.children=branchArr : '' //給父級新增一個children屬性,並賦值 return father.parentId==0; //返回第一層 }); }
根據網友給我指出的問題,之前的演算法會影響到源資料,之後我對獲取的資料進行了深度克隆,完美解決。
封裝函式:
function treeData(source,id,parentId,children){ let cloneData = JSON.parse(JSON.stringify(source)) return cloneData.filter(father=>{ let branchArr = cloneData.filter(child => father[id] == child[parentId]); branchArr.length>0 ? father[children] = branchArr : '' return father[parentId] == 0 // 如果第一層不是parentId=0,請自行修改 }) } // 呼叫時,欄位名以字串的形式傳參,如treeData(source,'id','parentId','children')
例項1:使用element-ui的元件製作一個樹形多級巢狀伸縮選單欄
實現效果:
vue元件:
<template> <el-tree :data="treeData" :props="defaultProps" accordion @node-click="handleNodeClick"> </el-tree> </template> <script> export default { name: "Test",data(){ return { data : [ {id:1,parentId:0,name:"一級選單A",rank:1},{id:2,name:"一級選單B",{id:3,name:"一級選單C",{id:4,parentId:1,name:"二級選單A-A",rank:2},{id:5,name:"二級選單A-B",{id:6,parentId:2,name:"二級選單B-A",{id:7,parentId:4,name:"三級選單A-A-A",rank:3},{id:8,parentId:7,name:"四級選單A-A-A-A",rank:4},{id:9,parentId:8,name:"五級選單A-A-A-A-A",rank:5},{id:10,parentId:9,name:"六級選單A-A-A-A-A-A",rank:6},{id:11,parentId:10,name:"七級選單A-A-A-A-A-A-A",rank:7},{id:12,parentId:11,name:"八級選單A-A-A-A-A-A-A-A",rank:8},{id:13,parentId:12,name:"九級選單A-A-A-A-A-A-A-A-A",rank:9},{id:14,parentId:13,name:"十級選單A-A-A-A-A-A-A-A-A-A",rank:10},],defaultProps: { children: 'children',label: 'name' } } },computed:{ treeData(){ let cloneData = JSON.parse(JSON.stringify(this.data)) // 對源資料深度克隆 return cloneData.filter(father=>{ let branchArr = cloneData.filter(child=>father.id == child.parentId) //返回每一項的子級陣列 branchArr.length>0 ? father.children = branchArr : '' //如果存在子級,則給父級新增一個children屬性,並賦值 return father.parentId==0; //返回第一層 }); } },methods:{ handleNodeClick(data){ // console.log(data) console.log(this.treeData) } },mounted(){ } } </script> <style scoped> </style>
Demo
樹形資料轉成扁平資料,請檢視這篇文章:js實現樹形資料轉成扁平資料