zoukankan      html  css  js  c++  java
  • JavaScript实现无限级递归树的示例代码

    原文链接:https://segmentfault.com/a/1190000018692367
    https://www.51xuediannao.com/javascript/digui_shu.html

    const data = [
        {
            "area_id": 5,
            "name": "广东省",
            "parent_id": 0,
        },  
        {
            "area_id": 6,
            "name": "广州市",
            "parent_id": 5,
        },
        {
            "area_id": 7,
            "name": "深圳市",
            "parent_id": 5,
        },
        {
            "area_id": 4,
            "name": "北京市",
            "parent_id": 3,
        },
        {
            "area_id": 3,
            "name": "北京",
            "parent_id": 0,
        },
        {
            "area_id": 2,
            "name": "测试子地区",
            "parent_id": 1,
        },
        {
            "area_id": 1,
            "name": "测试地区",
            "parent_id": 0,
        }
    ];
    
    function toTreeData(data,pid){
     
        function tree(id) {
            let arr = []
            data.filter(item => {
                return item.parent_id === id;
            }).forEach(item => {
                arr.push({
                    area_id: item.area_id,
                    label: item.name,
                    children: tree(item.area_id)
                })
            })
            return arr
        }
        return tree(pid)  // 第一级节点的父id,是null或者0,视情况传入
    };
    
    toTreeData(data,0)
    
    
    

    输出:

    改进:

    /**
     *
     * @param {*} replaceFields 替换 treeNode 中 title,key,children 字段为 treeData 中对应的字段
     * {children:'myChildren', title:'myTitle', key:'myKey', parentKey:'myParentKey' }
     * @returns
     */
    function getFiledMaps(replaceFields) {
      let filedMaps = {
        key: "key",
        title: "title",
        children: "children",
        parentKey: "parentKey",
      };
      if (replaceFields) {
        filedMaps = replaceFields;
      }
    
      return filedMaps;
    }
    
    /**
     * 将存在父子关系的 Aarry数据 转化成 Tree 结构
     * @param {Array} srcArr
     * @param {*} pKey 父节点的key,值为:null或0时,表示根节点
     * @param {*} replaceFields 替换 treeNode 中 title,key,children 字段为 treeData 中对应的字段
     * {children:'myChildren', title:'myTitle', key:'myKey', parentKey:'myParentKey' }
     * @returns
     */
    function toTreeData(srcArr, pkey, replaceFields) {
      const filedMaps = getFiledMaps(replaceFields);
      //pkey:父节点key
      function treeData(pkey) {
        let arr = [];
        srcArr
          .filter((item) => {
            return item[filedMaps["parentKey"]] === pkey;
          })
          .forEach((item) => {
            let node = {
              key: item[filedMaps["key"]],
              title: item[filedMaps["title"]],
              children: treeData(item[filedMaps["key"]]),
              parentKey: pkey,
            };
    
            arr.push(node);
          });
    
        return arr;
      }
      return treeData(pkey);
    }
    
    

    数据:

    var data = [
        {id: 1, address: "安徽", parent_id: 0},
        {id: 2, address: "江苏", parent_id: 0},
        {id: 3, address: "合肥", parent_id: 1},
        {id: 4, address: "庐阳区", parent_id: 3},
        {id: 5, address: "大杨镇", parent_id: 4},
        {id: 6, address: "南京", parent_id: 2},
        {id: 7, address: "玄武区", parent_id: 6},
        {id: 8, address: "梅园新村街道", parent_id: 7},
        {id: 9, address: "上海", parent_id: 0},
        {id: 10, address: "黄浦区", parent_id: 9},
        {id: 11, address: "外滩", parent_id: 10},
        {id: 12, address: "安庆", parent_id: 1}
    ];
    

    根据最后一个找到整个家族(家谱树)

    //根据最后一个找到整个家族
    function familyTree(arr, pid) {
        var temp = [];
        var forFn = function(arr, pid){
            for (var i = 0; i < arr.length; i++) {
                var item = arr[i];
                if (item.id == pid) {
                    temp.push(item);
    
                    forFn(arr,item.parent_id);
                }
            }
        };
        forFn(arr, pid);
        return temp;
    }
    
    //console.log(familyTree(data,10));
    

    从顶级往下找到所有的子子孙孙(子孙树)

    //子孙树,从顶级往下找到是有的子子孙孙
    function sonsTree(arr,id){
        var temp = [],lev=0;
        var forFn = function(arr, id,lev){
            for (var i = 0; i < arr.length; i++) {
                var item = arr[i];
                if (item.parent_id==id) {
                    item.lev=lev;
                    temp.push(item);
                    forFn(arr,item.id,lev+1);
                }
            }
        };
        forFn(arr, id,lev);
        return temp;
    }
    //console.log(sonsTree(data,0));
    

    利用子孙树生成一个树形dom结构(实例)

    //利用 子孙树 生成dom结构
    var tree = sonsTree(data,0);
    var temp = [];
    for(var i=0;i<tree.length;i++){
        var item = tree[i],u = "";
        if(i>0){
            u = "</ul>";
        }
        if(item['lev']==0){
            temp.push(u+'<li><a class="one">'+item.address+'</a><ul>');
        }else{
            temp.push('<li><a>'+item.address+'</a></li>')
        }
        if(i+1==tree.length){
            temp.push("</ul>")
        }
    }
    //console.log(temp.join(""));
    

    treeUtil.js

    使用 vue-adnt的tree组件 时,可以使用 treeUtil.js 进行数据适配

    
    /**
     * 获取原数据结构的映射字段
     * @param {*} replaceFields 替换 treeNode 中 title,key,children 字段为 treeData 中对应的字段
     * {children:'myChildren', title:'myTitle', key:'myKey', parentKey:'myParentKey',disabled:"myDisabled"}
     * @returns
     */
    function getFiledMaps(replaceFields) {
      let filedMaps = {
        key: "key",
        title: "title",
        children: "children",
        parentKey: "parentKey",
        disabled:"disabled",
        disableCheckbox:"disableCheckbox",
      };
      if (replaceFields) {
        filedMaps = replaceFields;
      }
    
      return filedMaps;
    }
    
    /**
     * 将存在父子关系的 Aarry数据 转化成 Tree 结构
     * @param {Array} srcArr
     * @param {*} pKey 父节点的key,值为:null或0时,表示根节点
     * @param {*} replaceFields 替换 treeNode 中 title,key,children 字段为 treeData 中对应的字段
     * {children:'myChildren', title:'myTitle', key:'myKey', parentKey:'myParentKey',disabled:"myDisabled"}
     * @returns
     */
    function toTreeData(srcArr, pkey, replaceFields) {
      const filedMaps = getFiledMaps(replaceFields);
      //pkey:父节点key
      function treeData(pkey) {
        let arr = [];
        srcArr
          .filter((item) => {
            return item[filedMaps["parentKey"]] === pkey;
          })
          .forEach((item) => {
            let node = {
              key: item[filedMaps["key"]],
              title: item[filedMaps["title"]],
              children: treeData(item[filedMaps["key"]]),
              parentKey: pkey,
              disabled:item[filedMaps["disabled"]],
              disableCheckbox:item[filedMaps["disableCheckbox"]],
            };
    
            arr.push(node);
          });
    
        return arr;
      }
      return treeData(pkey);
    }
    
    //根据某个节点,获取所有祖先节点
    function getFamilyTreeNodes(treeData, pkey) {
      var temp = [];
      var forFn = function(treeData, pkey) {
        for (var i = 0; i < treeData.length; i++) {
          var item = treeData[i];
          if (item.key == pkey) {
            temp.push(item);
    
            forFn(treeData, item.parentKey);
          }
        }
      };
      forFn(treeData, pkey);
      return temp;
    }
    
    function findTreeNode(treeData, key) {
      let parentNode = null;
      var forFn = function(treeData, key) {
        for (var i = 0; i < treeData.length; i++) {
          var item = treeData[i];
          if (item.key == key) {
            parentNode = item;
            break;
          } else {
            forFn(item.children, key);
          }
        }
      };
      forFn(treeData, key);
      return parentNode;
    }
    
    function getFamilyTreeNodeKeys(treeData, key) {
      const familykeys = [];
      const currNode = findTreeNode(treeData, key);
    
      if (currNode) {
        const familyNodes = getFamilyTreeNodes(treeData, currNode.parentKey);
        if (familyNodes) {
          familyNodes.forEach((n) => {
            familykeys.push(n.key);
          });
        }
      }
    
      return familykeys;
    }
    
    export { toTreeData, getFamilyTreeNodeKeys, getFamilyTreeNodes, findTreeNode };
    
    
    
    
  • 相关阅读:
    Ajax
    通过浏览器渲染过程来进行前端优化
    渲染树结构、布局和绘制
    JS 和 CSS 的位置对其他资源加载顺序的影响
    Linq中dbSet 的查询
    如何在windows“我的电脑”中添加快捷文件夹
    SQL Server中2008及以上 ldf 文件过大的解决方法
    出现“初始化数据库时发生异常”解决办法
    MVC使用ajax取得JSon数据
    asp.net mvc 使用Ajax调用Action 返回数据【转】
  • 原文地址:https://www.cnblogs.com/easy5weikai/p/14841057.html
Copyright © 2011-2022 走看看