js递归操作数据问题

image.png

一个树形结构的表格,在不同的操作后高亮行数据,会有多层子级,但是这么写递归有问题,报内存溢出错误,应该如何修改,感谢各位

// 递归选中高亮行
heightLight() {
    if (this.type === 'add' || this.type === 'addChild') {
        // 循环当前数组
        this.list.forEach((item, index) => {
            // 如果里面的id和当前操作前选中行的id相等,把当前数组的最后一行高亮
            if (item.id === this.selectRow.id) {
                this.$refs.productCategoryCateTable.setCurrentRow(this.list[this.list.length - 1])
                // 如果有子级做同样操作
            } else if (item.children.length > 0) {
                item.children.forEach((item2, index2) => {
                    if (item2.id === this.selectRow.id) {
                        console.log(this.list[index].children[this.list[index].children.length - 1],
                            'this.list[index].children[this.list[index].children.length-1]'
                        )
                        this.$nextTick(() => {
                            this.$refs.productCategoryCateTable.setCurrentRow(this.list[index].children[this.list[index].children.length - 1]
                            )
                        })
                    }
                    //如果还有子级递归
                    this.heightLight(item.children)
                })
            }
        })
    }
}
阅读 2.2k
2 个回答

且先不说方法写得好不好,很明显的一个错误:heightLight方法没有接收参数,递归里面又传了参数,这样就无限循环,当然就内存泄漏了。可以先这么改一下试试

heightLight(list = this.list) {
  if (this.type === 'add' || this.type === 'addChild') {
    // 循环当前数组
    list.forEach((item, index) => {
      // 如果里面的id和当前操作前选中行的id相等,把当前数组的最后一行高亮
      if (item.id === this.selectRow.id) {
        this.$refs.productCategoryCateTable.setCurrentRow(list[list.length - 1])
        // 如果有子级做同样操作
      } else if (item.children.length > 0) {
        item.children.forEach((item2, index2) => {
          if (item2.id === this.selectRow.id) {
            console.log(list[index].children[list[index].children.length - 1],
              'list[index].children[list[index].children.length-1]'
            )
            this.$nextTick(() => {
              this.$refs.productCategoryCateTable.setCurrentRow(list[index].children[list[index].children.length - 1]
              )
            })
          }
          //如果还有子级递归
          this.heightLight(item.children)
        })
      }
    })
  }
}

似乎没有必要去在某一层的逻辑中处理两层数据,我看第二层的数据处理逻辑和第一层是一样的,都是判断 ID,都是高亮最后一个子元素。

另外,this.list[index] 不就是 item 么?在 forEach 中直接使用 item 不好么 😂

下面我大致整理了一个示意代码,你看看

heightLight() {
    if (!(this.type === "add" || this.type === "addChild")) {
        return;
    }

    const selectRow = this.selectRow;
    const cateTable = this.$refs.productCategoryCateTable;

    // 递归入口,从这里开始
    highlight(this.list);

    // 把需要递归的部分抽取成一个函数。
    // 如果不想使用 selectRow 等临时变量,下面这个 highlight 可以声明为一个箭头函数,那就可以用 this 了
    function highlight(items) {
        if (items?.length ?? 0 <= 0) { return; }
        items.forEach((it) => {     // 为了避免把 items 和 item 看混淆,用 it 来代替 item
            if (it.id === selectRow.id) {
                cateTable.setCurrentRow(items[items.length - 1]);
                return;
            }
            // 直接递归就好,每一级都是一样的处理,不需要在一次里处理两级吧?
            highlight(it.children);
        });
    }
}
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题