js實現樹級遞歸,通過js生成tree樹形菜單(遞歸算法)


方法封裝:


/**
 * 數據轉換為樹形(遞歸),示例:toTreeByRecursion(source, 'id', 'parentId', null, 'children')
 * @param {Array} source 數據
 * @param {String} idField 標識字段名稱
 * @param {String} parentIdField 父標識字段名稱
 * @param {Any} parentIdNoneValue 父級標識空值
 * @param {String} childrenField 子節點字段名稱
 * @param {Object} treeOption tree樹形配置
 */function toTreeByRecursion (
  source = [],
  idField = 'id',
  parentIdField = 'parentId',
  parentIdNoneValue = '',
  childrenField = 'children',
  treeOption = undefined
) {
  const treeOptions = {
    enable: false, // 是否開啟轉tree插件數據
    keyField: 'key', // 標識字段名稱,默認為key
    valueField: 'value', // 值字段名稱,默認為value
    titleField: 'title', // 標題字段名稱,默認為title

    keyFieldBind: 'id', // 標識字段綁定字段名稱,默認為id
    valueFieldBind: 'id', // 值字段名稱綁定字段名稱,默認為id
    titleFieldBind: 'name' // 標題字段名稱綁定字段名稱,默認為name
  }
  // 合並tree樹形配置
  if (treeOption) {
    Object.assign(treeOptions, treeOption)
  }

  // 對源數據深度克隆
  const cloneData = JSON.parse(JSON.stringify(source))
  return cloneData.filter(parent => {
    // 返回每一項的子級數組
    const branchArr = cloneData.filter(child => parent[idField] === child[parentIdField])

    // 綁定tree樹形配置
    if (treeOptions.enable) {
      branchArr.map(child => {
        child[treeOptions.keyField] = child[treeOptions.keyFieldBind]
        child[treeOptions.valueField] = child[treeOptions.valueFieldBind]
        child[treeOptions.titleField] = child[treeOptions.titleFieldBind]
        return child
      })
    }

    // 如果存在子級,則給父級添加一個children屬性,並賦值,否則賦值為空數組
    if (branchArr.length > 0) {
      parent[childrenField] = branchArr
    } else {
      parent[childrenField] = []
    }

    // 綁定tree樹形配置
    if (treeOptions.enable) {
      parent[treeOptions.keyField] = parent[treeOptions.keyFieldBind]
      parent[treeOptions.valueField] = parent[treeOptions.valueFieldBind]
      parent[treeOptions.titleField] = parent[treeOptions.titleFieldBind]
    }

    return parent[parentIdField] === parentIdNoneValue // 返回第一層
  })
}

 

使用示例:


var jsonData = [
  {
    id: '1',
    name: '1',
    parentId: null,
    rank: 1
  },
  {
    id: '2',
    name: '1-1',
    parentId: '1',
    rank: 1
  },
  {
    id: '3',
    name: '1-2',
    parentId: '1',
    rank: 1
  },

  {
    id: '4',
    name: '2',
    parentId: null,
    rank: 1
  },
  {
    id: '5',
    name: '2-1',
    parentId: '4',
    rank: 1
  },
  {
    id: '6',
    name: '2-2',
    parentId: '4',
    rank: 1
  },
  {
    id: '7',
    name: '2-2-1',
    parentId: '6',
    rank: 1
  }
]
const treeOption = {
  enable: false, // 是否開啟轉tree插件數據
  keyField: 'key', // 標識字段名稱
  valueField: 'value', // 值字段名稱
  titleField: 'title', // 標題字段名稱

  keyFieldBind: 'id', // 標識字段綁定字段名稱
  valueFieldBind: 'id', // 值字段名稱綁定字段名稱
  titleFieldBind: 'name' // 標題字段名稱綁定字段名稱
}
const treeData = toTreeByRecursion(jsonData, 'id', 'parentId', null, 'children', treeOption)
console.log(treeData)

 

 

說明:


  • parentIdNoneValue 父級標識空值這個參數如果跟你數據無父級時的值不一致時,就配置這個參數。比如:這里默認值為null,你根節點parentId的值為-1或''。
  • treeOption 參數可以不傳,如果要綁定tree樹形控件(一般都會有key、value、title這三個字段),那就需要配置這個參數,如果參數默認的配置跟你的不一樣,那就通過參數覆蓋的方式重新定義
  • treeOption 的三個綁定字段是指綁定你數據中的字段,實質就是把原數據字段綁定的tree樹形控件需要的三個字段key、value、title。
  • 想到了再補充。。。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM