SOURCE

console 命令行工具 X clear

                    
>
console
const treeData = [
    {
        "id": 1,
        "name": "净值alpha类",
        "children": [
            {
                "id": '1-1',
                "name": '净值alpha1',
                "parentId": 1,
            },
            {
                "id": '1-2',
                "name": "风格择时",
                "parentId": 1,
            },
            {
                "id": '1-3',
                "name": "夏普alpha",
                "parentId": 1,
            },
        ]
    },
]
function gen_tree(childs){
  var html = ''
  childs.forEach(el => {
    html+=`<details open>
    <summary>
       <span class="tree-item" title="${el.name}" data-id="${el.id}">${el.name}</span>
    </summary>`
    if (el.children && el.children.length) {
      html += gen_tree(el.children) // 如果有chidren就继续遍历
    }
    html+= `</details>`
  })
  return html;
}
let tree = document.getElementById('tree')

tree.innerHTML = gen_tree(treeData)
<div class="tree" id="tree">
</div>
html,body{
    margin: 0;
    height: 100%;
}
::-webkit-details-marker {
    display: none;
}
::-moz-list-bullet {
    font-size: 0;
    float: left;
}
.tree{
    flex: 1;
    overflow: auto;
    padding: 4px 0;
    position: relative;
    width: 300px;
    height: 100%;
  margin: 0 auto;
}
.tree summary{
    outline: 0;
    padding-left: 30px;
    list-style: none;
    /* background: repeating-linear-gradient( 90deg, #999 0 1px,transparent 0px 2px) 0px 50%/20px 1px no-repeat; */
    background: linear-gradient(#999,#999) 0px 50%/20px 1px no-repeat;
}
.tree details:last-child{
    background-size: 1px 23px;
}
.tree>details:not(:last-child)>details:last-child{
    background-size: 1px 100%;
}
.tree details{
    padding-left: 40px;
    /* background: repeating-linear-gradient( #999 0 1px,transparent 0px 2px) 40px 0px/1px 100% no-repeat; */
    background: linear-gradient(#999, #999) 40px 0px/1px 100% no-repeat;
}
.tree>details{
    background: none;
    padding-left: 0;
}
.tree>details>summary{
    background: none
}
.tree summary{
    display: flex;
    align-items: center;
    height: 46px;
    font-size: 15px;
    line-height: 22px;
    color: rgba(0, 0, 0, 0.85);
    cursor: default;
}
.tree summary::after{
    content: '';
    position: absolute;
    left: 10px;
    right: 10px;
    height: 38px;
    background: #EEF2FF;
    border-radius: 8px;
    z-index: -1;
    opacity: 0;
    transition: .2s;
}
.tree summary:hover::after{
    opacity: 1;
}
.tree summary:not(:only-child)::before{
    content: '';
    width: 14px;
    height: 14px;
    flex-shrink: 0;
    margin-right: 8px;
    border: 1px solid #999;
    background: linear-gradient(#999, #999) 50%/1px 10px no-repeat,linear-gradient(#999, #999)  50%/10px 1px no-repeat;
}
.tree details[open]>summary::before{
    background: linear-gradient(#999, #999) 50%/10px 1px no-repeat;
}