因为数据库中存放的数据终究全是扁平化的,因此获取后要手动将其改成树形结构,方便el-tree进行渲染。
假设数据如下(至少是要有节点ID和父节点ID)
最终要达到如下效果(el-select的el-option下面直接写个树组件就能实现这个效果,为了方便展示在树组件外面加个滚动条)
递归函数如下:
/** * 将后台获取到的表转换为树形组件所需的结构 * @param arr value是递归数组,index是重新开始的位置,避免父级多次无效递归 * @returns {{index, value: [{ParentId: *, children: *[], name, id: *}]}|{index: *, value: [{ParentId: *, children: *[], name, id: *}]}} */ generateTreeNode(arr) { let index = arr.index let tree = arr.value //先获取第一个数组元素,尚不知道是叶节点还是树节点 let temp = [{ id: tree[index].NetId, name: tree[index].NetName, ParentId: tree[index].ParentId, children: [] }] //从当前位置+1开始循环。因为这里要递归深层,每次传的数组是原始数组 //所以需要获得结束递归后的新位置,方便下次循环使用 for (let m = index + 1; m < tree.length; m++) { //如果第二个节点的父节点是当前已处理数组末尾元素,则说明第一个节点是父节点,第二个是其子节点 //开始从第二个节点,进行递归 if (tree[m].ParentId === temp[temp.length - 1].id) { let children = this.generateTreeNode({value: tree, index: m}) // console.log('调用下一步', m, children) temp[temp.length - 1].children = children.value.slice() //-1,因为结束当前循环后默认m++,因此要往回退一位 m = children.index - 1 } //存在两种情况,若是子节点之间,则父节点相同,推入 //若是两个同级树节点,因为子节点已经结束了递归,所以这里推入的是父级数组 else if (tree[m].ParentId === tree[m - 1].ParentId || tree[m].ParentId === temp[temp.length - 1].ParentId) { // console.log('相同情况下的调用:', m, tree.length) temp.push({ id: tree[m].NetId, name: tree[m].NetName, ParentId: tree[m].ParentId, children: [] }) } //若下个节点的父节点和当前节点不对,则说明这一组的子节点已结束,结束递归 else if (tree[m].ParentId !== tree[m - 1].ParentId) { return {value: temp, index: m} } } console.log('这里是树形最终结果', temp) return {value: temp, index: tree.length} },
属性名更改为各自的结果即可。这个递归(实际上在循环那里m=index+1,这就表示这也是可以嵌套循环的来做的,只要你提前知道他有多少层)个人测试,4层数据200余行大概用了0.28ms(主要时间是后台请求时间)
不过这个存在一个问题,那就是极度依赖原始数据的排列顺序,因为是事先假设全部顺序排列的。
如果遇到下面这种情况,原本在某个父节点下的子节点,其【父节点】发生了变化,但它本身的id不变(顺序不变),这就会导致该递归终止,(因为我们是比较父节点是否相同来做判断的。这里它一层层得向上比较都不存在的话,就会直接终止)
因此你最好还是先刷一遍全部数据进行分组,再刷分组进行比较来形成树,这样就可以避免因为顺序问题而导致失败
可以想象为,第一种方法是先从根节点开始,然后一路衍生至一侧最底下的子节点,然后子节点结束后往上,第二组子节点,从左到右;
第二种方法就是全部从子节点开始,分组后一层层往上设置其对应的父节点,最终到达根节点(从下往上)。后者感觉明显要花时间了……想想咋实现吧,下次随笔写
标签:index,temp,tree,JS,children,树形,ParentId,原始数据,节点 From: https://www.cnblogs.com/ricardox3/p/16982889.html