JS tree structure processing (add, delete, search)

When encountering the following types of tree-structured lists, the list needs to be updated immediately when adding, modifying, or deleting.

 Data structure overview:

data = [
    {
        "id": 1,
        "pid": 0,
        "font_route": "",
        "api_action": "",
        "is_menu": 1,
        "is_show": 0,
        "title": "数据统计",
        "children": [
            {
                "id": 2,
                "pid": 1,
                "font_route": "/main/ActivityList",
                "api_action": "Index/getActivityList",
                "is_menu": 1,
                "is_show": 1,
                "title": "文章列表",
                "children": [
                    {
                        "id": 6,
                        "pid": 2,
                        "font_route": "/main/ArticleHot",
                        "api_action": "Index/getArticleHot",
                        "is_menu": 0,
                        "is_show": 1,
                        "title": "文章热度统计"
                    }
                ]
            }
        ]
    }
    
 ]

Then there are several options that can be achieved:

  1. refresh page
  2. Initiate a request to the server again to update the data
  3. Directly change the list data, and the view will be automatically refreshed in Vue.

 Both the first and second solutions require sending requests again to interact with the server, which is a waste of bandwidth and efficiency. Here we focus on the third method of directly modifying the data in this list.

If you directly modify the tree structure, the commonly used method is recursive operation. Through recursion, the tree structure can be added, deleted, and searched.

Add new object

Go directly to the basic code: [use id as the keyword and children as the subordinate field]

const handleData = (id, data, obj) => {
  data.forEach(item => {
    if (item.id === id) {
      item.children ? item.children.push(obj) : item.children = [obj]
    } else {
      if (item.children) {
        handleData(id, item.children, obj)
      }
    }
  })
  return data
}

Rewrite the function that can customize keywords and subordinate fields:

function insertTreeListItem (treeList, key , item , childField ,keyField) {

    var childField = arguments[3] ? arguments[3] : 'children'
    var keyField = arguments[4] ? arguments[4] : 'id'

    treeList.forEach(treeitem => {
      if (treeitem[keyField] === key) {
        treeitem[childField] ? treeitem[childField].push(item) : treeitem[childField] = [item]
      } else {
        if (treeitem[childField]) {
            insertTreeListItem(treeitem[childField], key , item , childField ,keyField)
        }
      }
    })
    return treeList
}

Please note when using vue:

If you directly use the above code to modify the original data in Vue, you will find that although the data is updated, sometimes the view is not updated. Attentive friends will soon discover that there are direct assignment statements for objects.

As we all know, the view cannot be updated during direct object assignment in vue2. In this case, since it is a public function, it is not possible to use this.$set assignment directly in the function. There are two solutions:

1. Let the backend add the children sub-item to each item, so that the front end does not need to use object assignment.
2. The front end does not directly pass in the value of data, but obtains a data through deep copy, and then reassigns the value back to data.

The second method is recommended here:

 Delete object

Deleting objects is relatively simple to write and is essentially recursive. Deletion does not need to return new data, and there is no problem in directly affecting the original array. If you need to return a new object, you can directly rewrite it.

Basic functions:

function removeTreeListItem(treeList, id) { // 根据id属性从数组(树结构)中移除元素
  if (!treeList || !treeList.length) {
    return
  }
  for (let i = 0; i < treeList.length; i++) {
    if (treeList[i].id === id) {
      treeList.splice(i, 1);
      break;
    }
    removeTreeListItem(treeList[i].children, id)
  }
}

Rewritten into a function that can customize keywords and subordinate fields

function removeTreeListItem(treeList, key , childField ,keyField) { 

    var childField = arguments[2] ? arguments[2] : 'children'
    var keyField = arguments[3] ? arguments[3] : 'id'

    if (!treeList || !treeList.length) {
      return
    }
    for (let i = 0; i < treeList.length; i++) {
      if (treeList[i][keyField] === key) {
        treeList.splice(i, 1);
        break;
      }
      removeTreeListItem(treeList[i][childField], key ,childField ,keyField)
    }
}

Find object

Basic functions:

getObjByTree = (data, id) => {
        let result = null
        if (!data) return // return; 中断执行
        for (let i in data) {
            if (result !== null) break
            let item = data[i];
            if (item.id=== id) {
                result = item;
                break;
            } else if (!!item?.children?.length) {
                result = this.getObjByTree(item.children, id);
            }
        }
        return result;
    }

Rewritten into a function that can customize keywords and subordinate fields

function searchTree(treeList, key , childField ,keyField){

    var childField = arguments[2] ? arguments[2] : 'children'
    var keyField = arguments[3] ? arguments[3] : 'id'

    let result = null
    if (!treeList) return // return; 中断执行
    for (let i in treeList) {
        if (result !== null) break
        let item = treeList[i];
        if (item[keyField]=== key) {
            result = item;
            break;
        } else if ( item[childField] && item[childField].length>0 ) {
            result = searchTree(item[childField], key);
        }
    }
    return result;
}

The above three functions should be able to solve most of the business codes related to tree structure data.

For more operations on tree-structured data, here is a recommended article: JS tree structure operations: search, traverse, filter, tree structure and list structure conversion - Muma Station

Guess you like

Origin blog.csdn.net/baidu_36095053/article/details/121649810