当菜单位置、层级发生变化时,重新计算菜单位置对应的路径
场景
系统有多个菜单及子菜单;假如菜单2进入到子菜单2-1的代码是 this.$router.push(子菜单的路径);此时将菜单2的子菜单2-1移动到菜单1下面,那么之前的this.$router.push(子菜单的路径)中子菜单路径就需要变化,需要重新计算子菜单的位置。
例如:
菜单1下有个子菜单为11。子菜单11当前路径是11,页面跳转需要的完整路径就是 /1/11,此时将子菜单11移动到菜单2下面,成为菜单2的子级;此时页面跳转完整路径就是/2/11
后台返回的数据,根据名称name查找路由访问的完整路径;后台像下面格式返回,前端可以直接用,后台也直接控制了前端路由;
后台返回数据示例:
1 var arr = [{ 2 name: '1',//一级菜单 3 path: '/1', 4 meta: { 5 title: '1' 6 }, 7 components: '1', 8 children: [{ 9 name: '11',//二级菜单 10 path: '11', 11 meta: { 12 title: '11' 13 }, 14 components: '11', 15 }] 16 }, { 17 name: '2',//一级菜单 18 path: '/2', 19 meta: { 20 title: '2' 21 }, 22 components: '2', 23 children: [{ 24 name: '21',//二级菜单 25 path: '21', 26 meta: { 27 title: '21' 28 }, 29 components: '21', 30 children: [{ 31 name: '211',//三级菜单 32 path: '211', 33 meta: { 34 title: '211' 35 }, 36 components: '211', 37 children: [{ 38 name: '2111',//四级菜单 39 path: '2111', 40 meta: { 41 title: '2111' 42 }, 43 components: '2111', 44 }] 45 }] 46 }] 47 }]
例如:
菜单名为11的当前路径是11,页面跳转需要的完整路径是 /1/11
菜单名为2111的当前路径是2111,页面跳转需要的完整路径是 /2/21/211/2111
第一步:找到当前路径
function find(list){ let path = '' //要返回的完整路径 for(var i=0;i<list.length;i++){ if(list[i].meta.title==='2111'){//找到了就返回 path = list[i].path return path }else{//没找到去看子集里面是否有,没有就下一个循环 if(list[i].children){ var a = find(list[i].children) if(a){ path = a return path } } } } } find(arr) //返回 2111,只是菜单名为2111的当前路径
第二步:尝试把父组件路径和当前组件路径拼接起来
1 function find(list,fpath){// fpath为父组件路径 2 let path = '' //要返回的完整路径 3 for(var i=0;i<list.length;i++){ 4 if(list[i].meta.title==='2111'){//找到了就返回 5 //path = list[i].path 6 path = fpath + (fpath?'/':'') + list[i].path 7 return path 8 }else{//没找到去看子集里面是否有,没有就下一个循环 9 if(list[i].children){ 10 //var a = find(list[i].children) 11 var a = find(list[i].children,list[i].path)//将当前组件的父组件的路径 list[i].path 传过去 12 if(a){ 13 path = a 14 return path 15 } 16 } 17 } 18 } 19 } 20 21 find(arr) //返回 211/2111 ,返回了父组件和当前组件拼接的路径
第三步:拼接所有祖先组件的路径,不管chilren嵌套多深,都能返回这一链路的完整路径
1 function find(list){ 2 let arr = Array.prototype.slice.call(arguments) 3 arr.shift()//得到传过来的所有祖先组件的路径 如菜单2111的祖先数据是[211,21,/2] 4 let path = '' //要返回的完整路径 5 for(let i=0;i<list.length;i++){ 6 if(list[i].meta.title==='2111'){//找到了就返回 7 //path = list[i].path 8 //path = fpath + (fpath?'/':'') + list[i].path 9 for(let j=arr.length-1;j>=0;j--){//循坏倒序遍历祖先路径数据 10 path += arr[j] + (arr[j]?'/':'') 11 } 12 path += list[i].path //拼接为 /2/21/211/2111 13 return path 14 }else{//没找到去看子集里面是否有,没有就下一个循环 15 if(list[i].children){ 16 //var a = find(list[i].children) 17 //var a = find(list[i].children,list[i].path)//将当前组件的父组件的路径 list[i].path 传过去 18 var a = find(list[i].children,list[i].path,...arr)//将当前组件的祖先组件的路径传过去 19 if(a){ 20 path = a 21 return path 22 } 23 } 24 } 25 } 26 } 27 28 find(arr) // 返回 /2/21/211/2111
这样不论菜单嵌套多深都能按照链路返回路径