在react中实现一个类似vue-route 效果的函数

334 阅读1分钟

#使用数组的reduce方法递归实现

const routes = [
{
 path: '/user', component: 1,
children: [
  {
    path: 'profile',
    component: 2
  },
  {
    path: '/posts',
    component: 3
  }
]
},
{
path: '/home', component: 1,
children: [
  {
    path: 'profile',
    component: 2
  },
  {
    path: '/posts',
    component: 3
  },
  {
    path: 'my',
    component: 3
  }
]
  }
]
//routers应该为权限前的
//如果需要设置权限  
function renderRoutes(routers) {  //将
let initMemo = [];
//递归调用
//封装一个reduce方法
function reduce(arr, _memo, parentPath = '') {
initMemo = arr.reduce((memo, val, index, array) => {
  // console.log(memo)
  //先进行对比,看是否有重复的 如果路由重复则进行报错处理
  if (val.path && val.component) {
    val.path.indexOf('/') != 0 && (val.path = '/' + val.path);
  } else {
    throw new Error('缺失path或component属性,请进行修改');
  }
  let flag = memo.some((item) => {
    return item.path == parentPath + val.path;
  });
  if (flag) {
    throw new Error(parentPath + val.path + '此path重名,请进行修改');
  }
  // memo.push({ ...val, path: parentPath + val.path });
  //判断val.children 是否存在
  if (val.children) {  
    if (!val.children instanceof Array) {
      throw new Error('children必须是个数组类型,请进行修改');
    };
    //如果有子路由,那么则需要该路由需要进行严格匹配
    !val.exact && (val.exact = true);
    memo.push({ ...val, path: parentPath + val.path });
    reduce(val.children, memo, val.path);
  } else {
    memo.push({ ...val, path: parentPath + val.path });
  }
  return memo;
    }, _memo);
 return initMemo;
}
return reduce(routers, initMemo);
};
console.log(renderRoutes(routes));
//这里面没有进行权限校验
//结果如下
/**
 * [ { path: '/user',
component: 1,
children: [ [Object], [Object] ],
exact: true },
 { path: '/user/profile', component: 2 },
 { path: '/user/posts', component: 3 },
{ path: '/home',
 component: 1,
  children: [ [Object], [Object], [Object] ],
   exact: true },
 { path: '/home/profile', component: 2 },
 { path: '/home/posts', component: 3 },
 { path: '/home/my', component: 3 } ]
 //将此数组进行map在Route组件中进行渲染即可
*/