由于项目中使用了react 及 ant-design ,在使用tree树型控件时,需要
类似下面的数据,
const treeData = [{ ?title: ‘0-0‘, ?key: ‘0-0‘, ?children: [{ ???title: ‘0-0-0‘, ???key: ‘0-0-0‘, ???children: [ ?????{ title: ‘0-0-0-0‘, key: ‘0-0-0-0‘ }, ?????{ title: ‘0-0-0-1‘, key: ‘0-0-0-1‘ }, ?????{ title: ‘0-0-0-2‘, key: ‘0-0-0-2‘ }, ???], ?}];
但是后台传输过来的往往是下面这样的路径字符串数组,这就需要我们进行转化为树形层级对象了。
var arr=[ ???"root/", ???"root/a/", ???"root/a/new_b.png", ???"root/a/qa/", ???"root/a/qa/新建文本文档 (3).txt", ???"root/asdfasdfasdfasdfasdfasdfasdf.txt", ???"root/b.png", ???"root/instqj_gfzqhk.exe", ???"root/jupyter_notebook.png", ???"root/new_b.png", ???"root/output/new_b.png", ???"root/soffice.exe", ???"root/ti/asdfasdfasdfasdfasdfasdfasdf.txt", ???"root/watermark.zip", ???"root/中华人民共和国国民经济和社会发展 第十三个五年规划纲要 .pdf", ???"root/国务院发布《中国制造2025》%28全文%29.pdf", ???"root/新建文本文档 (3).txt", ???"root/新建文本文档.txt", ???"root/沧海一声笑.docx", ???"root/理光C2011SP.exe"]
接下来我们开始行动
const pathToTree = (input) => { ???var output = []; ???for (var i = 0; i < input.length; i++) { ???????var chain = input[i].split("/"); ???????var currentNode = output; ???????for (var j = 0; j < chain.length; j++) { ???????????if (chain[j] === ‘‘) { ???????????????break; ???????????} ???????????var wantedNode = chain[j]; ???????????var lastNode = currentNode; ???????????for (var k = 0; k < currentNode.length; k++) { ???????????????if (currentNode[k].title == wantedNode) { ???????????????????currentNode = currentNode[k].children; ???????????????????break; ???????????????} ???????????} ???????????if (lastNode == currentNode) { ???????????????var newNode = currentNode[k] = { key: input[i], title: wantedNode, children: [] }; ???????????????currentNode = newNode.children; ???????????} else { ???????????????delete currentNode.children ???????????} ???????} ???} ???return output;}console.log(pathToTree(arr))
得到了我们想要的结果
光是这样还不够,我们使用ant-design中的tree树形控件,不能让最低层级有children属性,同时,我们自己也可以额外定一个需求:所有文件名字长度不能超过一定数量。
另外,由于我的项目是上传到亚马逊S3,有的文件夹不会返回给我,比如这个文件"root/ti/asdfasdfasdfasdfasdfasdfasdf.txt"就没有返回" root/ti/",所以我们要加上个层级数据。
我们这里遍历这个树型对象,简单处理一下
const traverseTree = function (data) { ???return data.map((item) => { ???????//如果有相同的key,react的渲染会有问题,所以要处理一下。 ???????let chain = item.key.split(‘/‘); ???????if (item.title !== chain.slice(-1)[0]) { ???????????item.key = chain.slice(0, -1).join(‘/‘) ???????} ???????item.title = item.title.length > 10 ? item.title.substring(0, 7) + "..." : item.title ???????if (item.children.length > 0) { ???????????traverseTree(item.children) ???????????return item ???????} else { ???????????delete item.children ???????????return item ???????} ???})}console.log(traverseTree(pathToTree(arr)))
输出结果