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。
- 想到了再补充。。。
嘴角上扬,记得微笑