方法封装:


/**
* 数据转换为树形(递归),示例: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。
  • 想到了再补充。。。

js实现树级递归,通过js生成tree树形菜单(递归算法)的更多相关文章

  1. js模仿块级作用域(js没有块级作用域私有作用域)

    js模仿块级作用域(js没有块级作用域私有作用域) 一.总结 1.js没有块级作用域:在for循环中定义的i,出了for循环还是有这个i变量 2.js可以模拟块级作用域:用立即执行的匿名函数:(匿名函 ...

  2. 菜鸟笔记:node.js+mysql中将JSON数据构建为树(递归制作树状菜单数据接口)

    初学Web端开发,今天是第一次将所学做随笔记录,肯定存在多处欠妥,望大家海涵:若有不足,望大家批评指正. 进实验室后分配到的第一个项目,需要制作一个不确定层级树形菜单的数据接口,对于从来没实战编过程的 ...

  3. js无限级树菜单

    以前做网站,树形菜单一般都很简单,自己定义风格样式,简单的js控制,后来原来网上很多文章都在讨论Js树型菜单,看了几个实例,发现这个树比较简单好用. http://hovertree.com/texi ...

  4. 用Vue.js递归组件构建一个可折叠的树形菜单

    在Vue.js中一个递归组件调用的是其本身,如: Vue.component('recursive-component', {   template: `<!--Invoking myself! ...

  5. Vue.js递归组件实现动态树形菜单

    使用Vue递归组件实现动态菜单 现在很多项目的菜单都是动态生成的,之前自己做项目也是遇到这种需求,翻看了官网案例,和网上大神的案例.只有两个感觉,官网的案例太简洁,没有什么注释,看起来不太好理解,大神 ...

  6. Vue.js 递归组件实现树形菜单

    最近看了 Vue.js 的递归组件,实现了一个最基本的树形菜单. 项目结构: main.js 作为入口,很简单: import Vue from 'vue' Vue.config.debug = tr ...

  7. 6个函数的output看JS的块级作用域

    1. var output = 0; (function() { output++; }()); console.log(output); 函数对全局的output进行操作,因为JS没有块级作用域,所 ...

  8. 下拉的DIV+CSS+JS二级树型菜单

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  9. JQuery 树状结构 jQuery-treeview.js 插件

    由简入繁实现Jquery树状结构 在项目中,我们经常会需要一些树状结构的样式来显示层级结构等,比如下图的样式,之前在学.net的时候可以直接拖个服务端控件过来直接使用非常方便.但是利用Jquery的一 ...

随机推荐

  1. PDO::getAvailableDrivers

    PDO::getAvailableDrivers — 返回一个可用驱动的数组(PHP 5 >= 5.1.0, PECL pdo >= 0.1.0) 说明 语法 static array P ...

  2. LeetCode 87,远看是字符串其实是搜索,你能做出来吗?

    本文始发于个人公众号:TechFlow,原创不易,求个关注 今天是LeetCode专题第54篇文章,我们一起来看LeetCode 87题,Scramble String(爬行字符串). 这题的官方难度 ...

  3. Ef Core增加Sql方法

    [AttributeUsage(AttributeTargets.Class|AttributeTargets.Method)] public class DbFunAttribute : Attri ...

  4. Windows系统护眼色设置

    Win10&Win8系统设置护眼色1. windows+R键调出运行窗口(或者鼠标右击开始键,选择运行)2. 在运行窗口中输入 regedit 调出注册表编辑器3. 按照如下顺序找到windo ...

  5. Java web 小测验

    题目要求: 1登录账号:要求由6到12位字母.数字.下划线组成,只有字母可以开头:(1分) 2登录密码:要求显示“• ”或“*”表示输入位数,密码要求八位以上字母.数字组成.(1分) 3性别:要求用单 ...

  6. Python笔试——毕业旅行问题

    毕业旅行问题 小明目前在做一份毕业旅行的规划.打算从北京出发,分别去若干个城市,然后再回到北京,每个城市之间均乘坐高铁,且每个城市只去一次.由于经费有限,希望能够通过合理的路线安排尽可能的省一些路上的 ...

  7. URL中加号(+)转义问题

    URL中加号(+)转义问题 前端通过URL传入一个参数,在后台日志中发现参数中的加号变成了空格. 前端传入a+b 后台日志a b 可以看到,+ 变成了空格. 先说结论 HTTP为了避免歧义,一些字符传 ...

  8. 尝试Access数据库注入实验

    靶场环境:https://www.mozhe.cn/bug/detail/82 首先http://219.153.49.228:49543/new_list.asp?id=1 order by 4 到 ...

  9. Django记录数据库创建、更新、删除操作开源插件推荐

    github: django-simple-history - 安装 $ pip install django-simple-history - 配置 在Settings中添加 INSTALLED_A ...

  10. 2020-06-02:千万级数据量的list找一个数据。

    福哥答案2020-06-02: 对于千万级长度的数组单值查找:序号小的,单线程占明显优势:序号大的,多线程占明显优势.单线程时间不稳定,多线程时间稳定. go语言测试代码如下: package mai ...