一、先说场景
在多层级菜单中,当点击某一个层级的菜单时需要打印该菜单的层级信息 如 首页-》子菜单-》列表项-》单条详情-》详情修改 要找出某一个结点的位置,打印出所在路径,
二、再说数据
菜单数据为数组对象数据,每个对象中必须含有唯一键字端,用于标示每个结点
[ { id: 'im01', name: '菜单-01', children : [ { id: 'im0101', name: '菜单-01-01', }, { id: 'im0102', name: '菜单-01-02', children: [ { id: 'im010201', name: '菜单-01-02-01', } ] }, { id: 'im0103', name: '菜单-01-03', } ] }, { id: 'im02', name: '菜单-02', children : [ { id: 'im0201', name: '菜单-02-01', }, { id: 'im0202', name: '菜单-02-02', }, { id: 'im0103', name: '菜单-02-03', } ] }, { id: 'im03', name: '菜单-03', children :[] } ]
三、上代码
const crumb = { _id : null, _children : null, _flat : [], _result: [], /** * 将输入菜单数据转化为一唯数组 * @param arrTree 菜单数据 * @param pid 从属结点id */ _conv_array: (arrTrue, pid = null) => { for(let i = 0; i< arrTrue.length; i++) { if(pid != "") { arrTrue[i]._parent_id = pid } crumb._flat.push(arrTrue[i]) if(undefined != arrTrue[i][crumb._children] && arrTrue[i][crumb._children].length != 0) { crumb._conv_array(arrTrue[i][crumb._children], arrTrue[i][crumb._id]) } } }, /** * 查找结点位置 * @param node 结点标识 */ _find_node: (node) => { for(let i in crumb._flat) { if(crumb._flat[i][crumb._id] == node){ crumb._result.push(crumb._flat[i]) } if(crumb._flat[i]._parent_id != undefined && crumb._flat[i][crumb._id] == node){ crumb._find_node(crumb._flat[i]._parent_id) } } }, /** * 查找结点所在位置 * @param tree 菜单数据 * @param find_id 查找结点的ID * @param id 唯一标示字段名称 * @param children 子节点字段标示名称 * @returns {T[]} */ find: (tree, find_id , id = "id" , children = "children") => { crumb._id = id crumb._children = children crumb._flat = [] crumb._result = [] crumb._conv_array(tree) crumb._find_node(find_id) return crumb._result.reverse() } }
四、使用方式
crumb.find(数据, 唯一表示字段值, 唯一标示字段名称, 子节点字段标示名称)
crumb.find(data, "im010201");
五、思路
1. 将多维菜单树通过crumb._conv_array函数进行一维展开的, 展开结果如下
[ {"id":"im01", "name":"菜单-01", "_parent_id":null}, {"id": "im0101", "name": "菜单-01-01", "_parent_id":"im01"}, {"id": "im0102", "name": "菜单-01-02", "_parent_id":"im01"}, {"id":"im010201","name":"菜单-01-02-01","_parent_id":"im0102"}, {"id":"im0103","name":"菜单-01-03","_parent_id":"im01"}, {"id":"im02","name":"菜单-02", "_parent_id":null}, {"id":"im0201","name":"菜单-02-01","_parent_id":"im02"}, {"id":"im0202","name":"菜单-02-02","_parent_id":"im02"}, {"id":"im0103","name":"菜单-02-03","_parent_id":"im02"}, {"id":"im03","name":"菜单-03","_parent_id":null} ]
2. 对一维数组进行递归查找,找出依赖链, 对查找结果进行反转,返回
crumb.find(data, 'im010201', 'id', 'children')
/ *** 结果 ***/ [ {"id":"im01","name":"菜单-01","_parent_id":null,"children":[ {"id":"im0101","name":"菜单-01-01","_parent_id":"im01"}, {"id":"im0102","name":"菜单-01-02","_parent_id":"im01","children": [ {"id":"im010201","name":"菜单-01-02-01","_parent_id":"im0102"} ] }, {"id":"im0103","name":"菜单-01-03","_parent_id":"im01"} ]}, {"id":"im0102","name":"菜单-01-02","_parent_id":"im01","children": [ {"id":"im010201","name":"菜单-01-02-01","_parent_id":"im0102"} ] }, {"id":"im010201","name":"菜单-01-02-01","_parent_id":"im0102"} ]