樹狀結構列表,這個技術點之前有寫過了,是基於vue講解,但似乎都沒有解決痛點,最基礎的原生JS該怎麼實現呢?
這篇文章會全面詳細的介紹樹狀結構列表的實現,從數據處理成樹狀結構,到動態生成dom節點渲染頁面。
確定原始數據結構
原始數據是需要按照下面這種結構來定義的,如果原始數據已經是被後端處理成樹狀結構,就可以省略這一步驟。
let data = [
{
"id": "1",
"name": "1",
"fatherId": "0",
},
{
"id": "2",
"name": "1-1",
"fatherId": "1"
},
{
"id": "3",
"name": "1-2",
"fatherId": "1"
},
{
"id": "4",
"name": "1-1-1",
"fatherId": "2"
},
{
"id": "5",
"name": "1-1-2",
"fatherId": "2"
},
{
"id": "6",
"name": "2",
"fatherId": "0"
},
{
"id": "7",
"name": "1-2-1",
"fatherId": "3"
}
];
使用map處理數據
const map = {};
const val = [];
data.forEach((item) => {
map[item.id] = item;
});
data.forEach((item) => {
const parent = map[item.fatherId];
if (parent) {
(parent.children || (parent.children = [])).push(item);
} else {
val.push(item);
}
});
把數組val打印出來看一下。
html結構
<div id="d0" class="treeItem"></div>
動態創建dom
將動態創建dom封裝成一個方法,裏面使用了遞歸。循環val數組調用這個方法,即可以實現動態創建dom。
const tree = document.getElementById("tree");
function createLi(data) {
const fid = `d${data.fatherId}`;
const div = document.getElementById(fid);
const treeItem = document.createElement("div");
treeItem.id = `d${data.id}`;
treeItem.className = "treeItem";
treeItem.innerHTML = data.name;
div.appendChild(treeItem);
if (data.children) {
data.children.forEach(d => {
createLi(d);
});
}
}
val.forEach(v => {
createLi(v);
})
css樣式
.treeItem > .treeItem{
padding-left: 10px;
cursor: pointer;
}
.itemIcon {
display: inline-block;
width: 10px;
height: 10px;
border-radius: 50%;
background: red;
margin-right: 10px;
}