一个人走路可能会孤单,但有一群人陪你将会奋勇直前、
关于递归的理解
1.函数调用自身
2.需要有结束条件 否则会进入死循环
3.提取重复的逻辑,优化代码结构
最近在使用 Vue 开发的一个后台管理系统时 由于需要根据权限生成动态路由,和获取路由标题 和 icon等需求 由于开始数据结构层级比较简单 只有简单的二级路由,所以就使用了双层 for循环遍历获取,
但由于后面需求的更新需要添更多的层级的功能模块,
于是想到了 两种方法解决:1.传统for多层级循环遍历 2.递归调用
原数据结构
let permission = [{
path: '/',
name: 'index',
component: BasicLayout,
meta: { title: '首页' },
redirect: '/api/router',
children: [
//客户管理
{
path: '/customer',
component: RouteView,
redirect: '/customer/AdminStration',
name: 'customer',
meta: { title: '客户管理', icon: 'github', keepAlive: true, permission: ['/customer/AdminStration'] },
children: [{
path: '/customer/AdminStration',
name: 'AdminStration',
component: () =>
import('@/views/customer/AdminStration'),
meta: { title: '客户管理', keepAlive: true, permission: ['AdminStration'] }
},]
},
//客户合同管理
{
path: '/contract',
component: RouteView,
redirect: '/contract/Contract',
name: 'contract',
meta: { title: '客户合同管理', icon: 'file-markdown', keepAlive: true, permission: ['/contract/Contract'] },
children: [{
path: '/contract/Contract',
name: 'Contract',
component: () =>
import('@/views/contract/Contract'),
meta: { title: '客户合同管理', keepAlive: true, permission: ['Contract'] }
},]
},
//市场活动管理
{
path: '/market',
component: RouteView,
redirect: '/market/Market',
name: 'market',
meta: { title: '市场活动管理', icon: 'shop', keepAlive: true, permission: ['/market/Market'] },
children: [{
path: '/market/Apply',
name: 'Apply',
component: () =>
import('@/views/market/Apply'),
meta: { title: '申请记录', keepAlive: true, permission: ['Apply'] }
},
{
path: '/market/Market',
name: 'Market',
component: () =>
import('@/views/market/Market'),
meta: { title: '全部活动', keepAlive: true, permission: ['Market'] }
},
]
},
//产品信息查看
{
path: '/product',
component: RouteView,
redirect: '/product/Product',
name: 'product',
meta: { title: '产品信息查看', icon: 'pound', keepAlive: true, permission: ['/product/Product'] },
children: [{
path: '/product/Product',
name: 'Product',
component: () =>
import('@/views/product/Product'),
meta: { title: '产品信息查看', keepAlive: true, permission: ['Product'] }
},]
},
//团队成员
{
path: '/team',
component: RouteView,
redirect: '/team/Team',
name: 'team',
meta: { title: '团队成员管理 ', icon: 'team', keepAlive: true, permission: ['/team/Team'] },
children: [{
path: '/team/Team',
name: 'Team',
component: () =>
import('@/views/team/Team'),
meta: { title: '团队成员管理', keepAlive: true, permission: ['Team'] }
},]
},
//权限管理
{
path: '/jurisdiction',
component: RouteView,
redirect: '/jurisdiction/jurhome',
name: 'Jurisdiction',
meta: { title: '权限管理 ', icon: 'user', keepAlive: true, permission: ['/jurisdiction/jurhome'] },
children: [{
path: '/jurisdiction/jurhome',
name: 'Jurhome',
component: () =>
import('@/views/jurisdiction/JuriHome'),
meta: { title: '企业首页', keepAlive: true, permission: ['Jurhome'] }
},
{
path: '/jurisdiction/staff',
name: 'staff',
component: () =>
import('@/views/jurisdiction/Staff'),
meta: { title: '员工与部门管理', keepAlive: true, permission: ['staff'] }
},
{
path: '/jurisdiction/userrole',
name: 'UserRole',
component: () =>
import('@/views/jurisdiction/UserRole'),
meta: { title: '角色权限控制', keepAlive: true, permission: ['UserRole'] }
},
{
path: '/jurisdiction/approval',
name: 'Approval',
component: () =>
import('@/views/jurisdiction/Approval'),
meta: { title: '审批流程管理', keepAlive: true, permission: ['Approval'] }
},
]
},
//资金及审核管理
{
path: '/capital',
component: RouteView,
redirect: '/capital/moneygrade',
name: 'Jurisdiction',
meta: { title: '资金及审核管理 ', icon: 'money-collect', keepAlive: true, permission: ['/capital/moneygrade'] },
children: [{
path: '/capital/moneygrade',
name: 'moneygrade',
component: () =>
import('@/views/capital/MoneyGrade'),
meta: { title: '打款信息审核', keepAlive: true, permission: ['MoneyGrade'] }
},
{
path: '/capital/makemoney',
name: 'makemoney',
component: () =>
import('@/views/capital/MakeMoney'),
meta: { title: '佣金发放审核报批', keepAlive: true, permission: ['MakeMoney'] }
},
{
path: '/capital/moneygrant',
name: 'MoneyGrant',
component: () =>
import('@/views/capital/MoneyGrant'),
meta: { title: '佣金级别管理', keepAlive: true, permission: ['MoneyGrant'] }
},
{
path: '/capital/delcontract',
name: 'delcontract',
component: () =>
import('@/views/capital/DelContract '),
meta: { title: '合同报废核销', keepAlive: true, permission: ['DelContract'] }
},
]
},
//客户及产品管理
{
path: '/prodectmanage',
component: RouteView,
redirect: '/prodectmanage/userdata',
name: 'Jurisdiction',
meta: { title: '客户及产品管理 ', icon: 'desktop', keepAlive: false, permission: ['/prodectmanage/userdata'] },
children: [{
path: '/prodectmanage/userdata',
name: 'UserData',
component: () =>
import('@/views/prodectmanage/UserData'),
meta: { title: '客户资料', keepAlive: false, permission: ['UserData'] }
},
{
path: '/prodectmanage/contrancexamie',
name: 'ContrancExamie',
component: () =>
import('@/views/prodectmanage/ContrancExamie'),
meta: { title: '合同权限审核', keepAlive: false, permission: ['ContrancExamie'] }
},
{
path: '/prodectmanage/usermaintain',
name: 'UserMaintain',
component: () =>
import('@/views/prodectmanage/UserMaintain'),
meta: { title: '客户维护', keepAlive: false, permission: ['UserMaintain'] }
},
{
path: '/prodectmanage/productinfo',
name: 'ProductInfo',
component: RouteView,
redirect: '/prodectmanage/productinfo/datacensus',
meta: { title: '产品信息管理', keepAlive: true, permission: ['datacensus'] },
children: [{
path: '/prodectmanage/productinfo/manage',
name: 'Manage',
component: () =>
import('@/views/prodectmanage/ProductInfo/Manage'),
meta: { title: '产品信息', keepAlive: true, permission: ['Manage'] },
},
{
path: '/prodectmanage/productinfo/datacensus',
name: 'DataCensus',
component: () =>
import('@/views/prodectmanage/ProductInfo/DataCensus'),
meta: { title: '数据统计', keepAlive: true, permission: ['DataCensus'] },
},
{
path: '/prodectmanage/productinfo/echart',
name: 'Echart',
component: () =>
import('@/views/prodectmanage/ProductInfo/Echarts'),
meta: { title: '产品销售情况', keepAlive: true, permission: ['Echarts'] },
},
]
},
{
path: '/prodectmanage/contrancmanage',
name: 'ContrancManage',
component: () =>
import('@/views/prodectmanage/ContrancManage'),
meta: { title: '合同管理', keepAlive: true, permission: ['ContrancManage'] }
},
]
},
//市场活动管理
{
path: '/marketing',
component: RouteView,
redirect: '/marketing/plan',
name: 'Marketing',
meta: { title: '市场活动管理 ', icon: 'radar-chart', keepAlive: false, permission: ['/marketing/plan'] },
children: [{
path: '/marketing/plan',
name: 'Plan',
component: () =>
import('@/views/marketing/Plan'),
meta: { title: '市场活动策划', keepAlive: false, permission: ['Plan'] }
},
{
path: '/marketing/activitymanage',
name: 'ActivityManage',
component: () =>
import('@/views/marketing/ActivityManage'),
meta: { title: '活动管理', keepAlive: false, permission: ['ActivityManage'] }
},
{
path: '/marketing/activityApply',
name: 'activityApply',
component: () =>
import('@/views/marketing/ActivityApply'),
meta: { title: '活动申请管理', keepAlive: false, permission: ['activity-apply'] }
}
]
},
//后台接口管理
{
path: '/api',
component: RouteView,
redirect: '/api/router',
name: 'Api',
meta: { title: '后台接口管理 ', icon: 'key', keepAlive: true, permission: ['/api/router'] },
children: [{
path: '/api/router',
name: 'router',
component: () =>
import('@/views/apirouter/ApiRouter'),
meta: { title: '后台接口菜单', keepAlive: true, permission: ['/api/router'] }
},]
},
]
},]
需要获取到 每个页面的title
普通forEach 循环获取
/*普通循环*/
var roleList = []
permission.forEach(itemT1 => {
roleList.push(itemT1.meta.title)
itemT1.children.forEach(itemT2 => {
roleList.push(itemT2.meta.title)
itemT2.children.forEach(itemT3 => {
roleList.push(itemT3.meta.title)
if (itemT3.children) {
itemT3.children.forEach(itemT4 => {
roleList.push(itemT4.meta.title)
})
}
})
})
})
console.log(roleList)
页面打印
虽然成功拿到每个页的 title 但多层级 的forEach 遍历 着实看着恶心,如果再添加数据结构层级还需要添加循环,而且不方便后期维护
采用递归的方法
/*递归调用*/
function setRole(permission) {
let roleList = []
function setPermission(permission) {
permission.map(role => {
roleList.push(role.meta.title) //将每次遍历的 title 存入数组中
if (role.children) { //递归结束条件 如果有 子页面 children 将该数据执行调用
setPermission(role.children)
}
})
}
setPermission(permission)
return roleList //返回遍历结果
}
let role = setRole(permission)
console.log(role)
页面打印
结果一样,每个页面的title都能拿到,代码结构更加简洁易懂,如果需要在添加更深层次的数据结构 只需增加原数据结构即可,功能代码无需修改便于后期维护功能迭代
个人关于递归的理解:
1.多用于 省 市 县,多层树形结构数据遍历
2.重复的逻辑调用
3.一定要有结束调用条件
4.优化代码结构
5.阶乘算法(虽然没用过!!!)