公告:携程招聘java、前端、测试、产品等,请发简历至374947554@qq.com,帮内推!

js查找树结构某元素,并找到其所有祖先

2908次浏览

前言

写了一个类似element ui的级联面板的那个组件,不同的是,组件可以类似tree选择,选择某个子元素,就返回单个子元素,选择所有子元素,返回父元素。回头整理一下。开源出来。

难点

感觉难点就是数据回填,数据操作倒是不是很难。

数据操作思路:

选中某个节点,然后根据其parent_id,递归查找父元素。假如子元素个数和选中个数相等,父元素选中,不相等,则所有父元素半选状态。

数据回填就稍微麻烦一点

首先:递归查找到要回填的数据,使其状态为选中,假如选中的数据有子元素,则所有子元素选中。

其次,找到选中数据的所有父元素,然后改变其状态,使其变为半选。然后对数据进行一个展示。

部分代码

递归查找所有父元素代码:

  findAllParent(node, tree, parentNodes = [], index = 0) {
      if (!node || !node[this.sprops.parent]) {
        return
      }
      this.findParent(node, parentNodes, tree)
      let parentNode = parentNodes[index]
      this.findAllParent(parentNode, tree, parentNodes, ++index)
      return parentNodes
    },
    findParent (node, parentNodes, tree) {
      for (let i = 0; i < tree.length; i++) {
        let item = tree[i]
        if (item[this.sprops.value] === node[this.sprops.parent]) {
          parentNodes.push(item)
          return
        }
        if (item.children && item.children.length > 0) {
          this.findParent(node, parentNodes, item.children)
        }
      }
    },

递归查找当前节点源码

 getCheckedNodes(data, value) {
      data.forEach(item => {
        if (value === item[this.sprops.value]) {
          this.checkedNodes.push(item)
          this.$set(item, 'checked', true)
          this.$set(item, 'isIndeterminate', false)
          this.childrenChecked(item, true)
        } else {
          if (item.children && item.children.length > 0) {
            this.getCheckedNodes(item.children, value)
          }
        }
      })
    },

回填代码,对所有父元素进行半选。

 valForeach(val) { 
      val.forEach(item => {
        this.getCheckedNodes(this.options, item)
      })
      let checkednodeTree = {}
      this.checkedNodes.forEach(node => {
        checkednodeTree[node[this.sprops.value]] = this.findAllParent(node, this.options)
      })
      // console.log(checkednodeTree)
      for (let key in checkednodeTree) {
        if (checkednodeTree[key] && checkednodeTree[key].length > 0) {
          let parentArray = checkednodeTree[key].reverse()
          parentArray.forEach((item, index) => {
            this.$set(item, 'isIndeterminate', true)
            this.onelineClick(item, index + 1, 'init')
          })
        }
      }
    },

上述就是对于查找树结构,循环递归查找节点的一些介绍。

Tags: jsjs tree

相关文章: