react big data Tree组件

项目需求遇到一个需渲染超大树结构数据,antd官方提供的tree组件并不能满足,因此通过网上资料自己写了一个big tree的组件;

主要参照:

https://github.com/Bowiezhang/vue-bigDataTree,但原文是基于vue的组件,且对于数据格式没有说明,因此写下本博客方便后人使用;

核心原理:

div下属两个div,

一个div  (real-tree-wrapper)代表真实的树高度,该树仅起支撑div的作用;

另一个div  (virtual-tree-wrapper) 渲染当前可见的数据;通过translateY 来达到动态渲染的效果

经实践,可流畅渲染万级别节点数量; 通过设置tree的属性,可与搜索跳转联动,

 

 

使用方式:

        <Tree treeData ={tree}  />  

check和selec的回调函数入口,回调的数据为当前点击的项,item.id 和check状态等会一并返回

<BigTree
        onCheck={onCheck}
        ref={refBigTree}
        onSelect={onSelect}
        treeData={treeData} />

 

对于treeData的格式:

一般后端返回的都是树形结构数据,首先要将数据拍平为一维的,当前节点的唯一标识为id,父节点为pId,level为节点的层级,为方便,将根节点push到最后一个;,子组件会默认取最后一个节点进行渲染;

处理函数如下:

let iniData = {"机电系统":{"电气":{"照明":{"照明配件":[{"name":"壁灯05","key":"M1612423944677_279635"},{"name":"壁灯05","key":"M1612423944677_279673"}]}},"给排水":{"卫生洁具":[{"name":"台式洗脸盆","key":"M1612423944677_246705"},{"name":"台式洗脸盆","key":"M1612423944677_247375"},{"name":"1200 x 1200 mm","key":"M1612423944677_248138"},{"name":"1524 x768x 356 mm","key":"M1612423944677_250291"},{"name":"760 x 535 mm","key":"M1612423944677_281687"},{"name":"M_小便池-墙-三维","key":"M1612423944677_244765"},{"name":"M_盥洗室-家用-三维","key":"M1612423944677_244449"},{"name":"M_盥洗室-家用-三维","key":"M1612423944677_247372"}]},"设备":{"特殊设备":[{"name":"305 x 457 mm","key":"M1612423944677_265272"},{"name":"600 x 490 mm","key":"M1612423944677_265916"}]}},"建筑":{"窗":[{"name":"MWC0818","key":"M1612423944677_229965"},{"name":"MWC0818","key":"M1612423944677_229980"},{"name":"MWC0818","key":"M1612423944677_229990"},{"name":"MWC0818","key":"M1612423944677_231080"},{"name":"MWC0818","key":"M1612423944677_231082"},{"name":"MWC0818","key":"M1612423944677_231084"},{"name":"MWC0818","key":"M1612423944677_231923"},{"name":"MWC0818","key":"M1612423944677_231924"},{"name":"MWC0818","key":"M1612423944677_231925"},{"name":"MWC1518","key":"M1612423944677_229211"},{"name":"MWC1518","key":"M1612423944677_229360"},{"name":"MWC1518","key":"M1612423944677_229488"},{"name":"MWC1518","key":"M1612423944677_229556"},{"name":"MWC1518","key":"M1612423944677_229620"},{"name":"MWC1518","key":"M1612423944677_229726"},{"name":"MWC1518","key":"M1612423944677_230041"},{"name":"MWC1518","key":"M1612423944677_231068"},{"name":"MWC1518","key":"M1612423944677_231070"},{"name":"MWC1518","key":"M1612423944677_231072"},{"name":"MWC1518","key":"M1612423944677_231074"},{"name":"MWC1518","key":"M1612423944677_231076"},{"name":"MWC1518","key":"M1612423944677_231078"},{"name":"MWC1518","key":"M1612423944677_231086"},{"name":"MWC1518","key":"M1612423944677_231475"},{"name":"MWC1518","key":"M1612423944677_231518"},{"name":"MWC1518","key":"M1612423944677_231921"},{"name":"MWC1518","key":"M1612423944677_231922"},{"name":"MWC1518","key":"M1612423944677_231945"}],"栏杆扶手":[{"name":"坡道扶手","key":"M1612423944677_239854"},{"name":"园艺栏杆","key":"M1612423944677_237997"},{"name":"园艺栏杆","key":"M1612423944677_238640"},{"name":"园艺栏杆","key":"M1612423944677_239660"},{"name":"900mm 圆管 栏杆落在踏面","key":"M1612423944677_236295"}],"楼板":[{"name":"常规 140 - 20+120","key":"M1612423944677_232351"},{"name":"常规 140 - 20+120","key":"M1612423944677_232405"},{"name":"常规 140 - 20+120","key":"M1612423944677_232463"},{"name":"常规 140 - 20+120","key":"M1612423944677_237566"},{"name":"常规 140 - 20+120","key":"M1612423944677_238631"},{"name":"常规 140 - 20+120","key":"M1612423944677_239624"}],"楼梯":[{"name":"家用-150 x 250mm","key":"M1612423944677_235644"}],"门":[{"name":"M0821","key":"M1612423944677_226859"},{"name":"M0821","key":"M1612423944677_227126"},{"name":"M0821","key":"M1612423944677_227386"},{"name":"M0821","key":"M1612423944677_227441"},{"name":"M0821","key":"M1612423944677_227488"},{"name":"M0821","key":"M1612423944677_227538"},{"name":"M0821","key":"M1612423944677_231050"},{"name":"M0821","key":"M1612423944677_231060"},{"name":"M0821","key":"M1612423944677_231156"},{"name":"M0821","key":"M1612423944677_231166"},{"name":"M0821","key":"M1612423944677_231226"},{"name":"M0821","key":"M1612423944677_231271"},{"name":"M0821","key":"M1612423944677_231323"},{"name":"M0821","key":"M1612423944677_231474"},{"name":"M0821","key":"M1612423944677_231869"},{"name":"M0821","key":"M1612423944677_231870"},{"name":"M0821","key":"M1612423944677_231920"},{"name":"M1221","key":"M1612423944677_227671"},{"name":"M1521","key":"M1612423944677_227592"},{"name":"M1521","key":"M1612423944677_231409"},{"name":"M1521","key":"M1612423944677_231871"},{"name":"M2520","key":"M1612423944677_228293"}],"坡道":[{"name":"坡道1/5","key":"M1612423944677_236689"},{"name":"坡道1/5","key":"M1612423944677_237189"}],"墙":[{"name":"常规 - 240mm-20+200+20","key":"M1612423944677_222627"},{"name":"常规 - 240mm-20+200+20","key":"M1612423944677_222669"},{"name":"常规 - 240mm-20+200+20","key":"M1612423944677_222770"},{"name":"常规 - 240mm-20+200+20","key":"M1612423944677_222817"},{"name":"常规 - 240mm-20+200+20","key":"M1612423944677_223145"},{"name":"常规 - 240mm-20+200+20","key":"M1612423944677_223263"},{"name":"常规 - 240mm-20+200+20","key":"M1612423944677_223313"},{"name":"常规 - 240mm-20+200+20","key":"M1612423944677_223354"},{"name":"常规 - 240mm-20+200+20","key":"M1612423944677_225217"},{"name":"常规 - 240mm-20+200+20","key":"M1612423944677_225218"},{"name":"常规 - 240mm-20+200+20","key":"M1612423944677_225220"},{"name":"常规 - 240mm-20+200+20","key":"M1612423944677_225221"},{"name":"常规 - 240mm-20+200+20","key":"M1612423944677_225586"},{"name":"常规 - 240mm-20+200+20","key":"M1612423944677_225651"},{"name":"常规 - 240mm-20+200+20","key":"M1612423944677_231864"},{"name":"常规 - 240mm-20+200+20","key":"M1612423944677_231865"},{"name":"常规 - 240mm-20+200+20","key":"M1612423944677_231866"},{"name":"外保温墙350mm- 20+60+240+30","key":"M1612423944677_220975"},{"name":"外保温墙350mm- 20+60+240+30","key":"M1612423944677_221014"},{"name":"外保温墙350mm- 20+60+240+30","key":"M1612423944677_221055"},{"name":"外保温墙350mm- 20+60+240+30","key":"M1612423944677_221098"},{"name":"外保温墙350mm- 20+60+240+30","key":"M1612423944677_221141"},{"name":"外保温墙350mm- 20+60+240+30","key":"M1612423944677_221185"},{"name":"外保温墙350mm- 20+60+240+30","key":"M1612423944677_221239"},{"name":"外保温墙350mm- 20+60+240+30","key":"M1612423944677_221299"},{"name":"外保温墙350mm- 20+60+240+30","key":"M1612423944677_221337"},{"name":"外保温墙350mm- 20+60+240+30","key":"M1612423944677_221439"},{"name":"外保温墙350mm- 20+60+240+30","key":"M1612423944677_221482"},{"name":"外保温墙350mm- 20+60+240+30","key":"M1612423944677_222134"},{"name":"外保温墙350mm- 20+60+240+30","key":"M1612423944677_223454"},{"name":"外保温墙350mm- 20+60+240+30","key":"M1612423944677_224378"},{"name":"外保温墙350mm- 20+60+240+30","key":"M1612423944677_225473"},{"name":"外保温墙350mm- 20+60+240+30","key":"M1612423944677_231592"},{"name":"外保温墙350mm- 20+60+240+30","key":"M1612423944677_231716"}],"屋顶":[{"name":"架空隔热保温屋顶 - 混凝土","key":"M1612423944677_232775"},{"name":"架空隔热保温屋顶 - 混凝土","key":"M1612423944677_234936"}],"柱":[{"name":"350 x 350mm","key":"M1612423944677_217082"},{"name":"350 x 350mm","key":"M1612423944677_217223"},{"name":"350 x 350mm","key":"M1612423944677_217248"}]},"结构":{"结构柱":[{"name":"300 x 300mm","key":"M1612423944677_218596"},{"name":"300 x 300mm","key":"M1612423944677_218671"},{"name":"300 x 300mm","key":"M1612423944677_218824"},{"name":"300 x 300mm","key":"M1612423944677_218849"},{"name":"300 x 300mm","key":"M1612423944677_218900"},{"name":"300 x 300mm","key":"M1612423944677_218953"},{"name":"300 x 300mm","key":"M1612423944677_219032"},{"name":"300 x 300mm","key":"M1612423944677_219151"},{"name":"300 x 300mm","key":"M1612423944677_219214"},{"name":"300 x 300mm","key":"M1612423944677_219267"},{"name":"300 x 300mm","key":"M1612423944677_219352"},{"name":"300 x 300mm","key":"M1612423944677_219486"},{"name":"300 x 300mm","key":"M1612423944677_219726"},{"name":"300 x 300mm","key":"M1612423944677_219727"},{"name":"300 x 300mm","key":"M1612423944677_219728"},{"name":"300 x 300mm","key":"M1612423944677_222487"},{"name":"300 x 300mm","key":"M1612423944677_222516"}]},"装饰":{"橱柜":[{"name":"0300 mm","key":"M1612423944677_254993"},{"name":"1000 mm","key":"M1612423944677_255079"},{"name":"250 mm","key":"M1612423944677_262694"},{"name":"300 mm","key":"M1612423944677_261971"},{"name":"600 mm","key":"M1612423944677_259622"},{"name":"600 mm","key":"M1612423944677_260474"},{"name":"600 mm","key":"M1612423944677_260535"},{"name":"600 mm","key":"M1612423944677_260569"},{"name":"600mm 深","key":"M1612423944677_257035"},{"name":"900 mm","key":"M1612423944677_255355"},{"name":"900 mm","key":"M1612423944677_256164"},{"name":"900 mm","key":"M1612423944677_257865"}]}}
let tree = []
function createGuid() {
  // http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript
  return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function (c) {
      var r = (Math.random() * 16) | 0;
      var v = c === "x" ? r : (r & 0x3) | 0x8;
      return v.toString(16);
  });
}
function flatTreeData (jsonData,rootId,rootLevel) {
  let tree = [];
  function getJsonTree (json,pid,level) {
    for(var key in json ){

      //如果是数组,则没有children了
      let id = createGuid()
      if(json[key] instanceof Array){
        tree.push({name:key,pId:pid,id:id,level:level,hasChildren:true,checked:false})
        json[key].map( v => {
          tree.push({name:v.name,pId:id,id:createGuid(),level:level+1,hasChildren:false,checked:false,key:v.key})
        })
      }
      //如果是对象,则还有children
      else{
        //将本节点加入tree,并递归子节点

        tree.push({name:key,pId:pid,id:id,level:level,hasChildren:true,checked:false})
        getJsonTree(json[key],id,level+1)
      }
    }

  }
  getJsonTree(jsonData,rootId,rootLevel)
  return tree
}
let rootid = createGuid();
tree = flatTreeData(iniData,rootid,1)
for(let i=0;i<10000;i++){
  tree.push({name:'test'+i,pId:rootid,id:'rootid'+i,level:0,visible:true,expand:false,hasChildren:true,checked:true})
}
tree.push({name:'gen',pId:0,id:rootid,level:0,visible:true,expand:false,hasChildren:true,checked:true});

 

git地址

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值