实现动态路由,需要解决3个核心功能

1、router.addRoute 方法加路由

2、动态集成路由componentName:() => import(`@/pages/${view}`)

3、刷新后动态路由丢失问题

总体思路:

1、定义一个store对象,这个是vue里面的全局对象,刷新后值会丢失

2、登录后把数据库的菜单调用router.addRoute加到路由中,然后把菜单存本地localstore

3、router.beforeEach 里面判断是否登录,且store对象里面的值是否为空,然后直接重新去localstore再绑定一次路由,调用next({ ...to, replace: true });重来即可

1、2的实现代码如下:

//绑定动态路由
router.initRouter=(menuList)=>{
  var routerConfig={ path: '/', name: 'home', component: () => import('@/layouts/PageLayout'),
    children: [
      { path: "/404", name: '404', component: () => import('@/common/error/404'),
        meta: {
          //原组件的名称
          componentName: "Page404",
          //不需要登录
          needLogin: false
        }
      },
    ]
  };
  //循环数据库的菜单
  for(var menu of menuList){
    //没有数据的不绑定
    if(menu.component_path==undefined || menu.component_path ==null || menu.component_path=="" || menu.component_path=="null"){
      continue;
    }
    routerConfig.children.push({
      path: menu.url,
      component: loadComponent(menu.component_path),
      meta: {
        componentName: menu.component_name
      }
    });
  }
  router.addRoute(routerConfig);
  router.addRoute({path: '*',redirect: '/404', hidden: true });
  //动态路由加载完成
  store.state.menu.dynRouterLoaded = true;
}
//路由的插件
const loadComponent = (view) => {
  if(view.substring(0,1)=="/"){
    view=view.substring(1);
  }
  if (process.env.NODE_ENV === 'development') {
    return (resolve) => require([`@/pages/${view}`], resolve)
  } else {
    // 使用 import 实现生产环境的路由懒加载
    return () => import(`@/pages/${view}`)
  }
}

解决刷新丢失路由


//路由前置守卫
router.beforeEach((to, from, next) => {
  NProgress.start();
  //有登录且没有路由的时候,手动绑定一次路由,解决刷新菜单丢失问题
  if(getAuthorization()!=null&& store.state.menu.dynRouterLoaded==false){
    var localMenus = localStorage.getItem(process.env.ADMIN_MENUS_KEY)
    if (localMenus != null) {
       router.initRouter(JSON.parse(localMenus));
    }else{
      router.initRouter([]);
    }
    next({ ...to, replace: true });
  }
  
  if (to.meta.needLogin == false) {
    //不需要登录
    return next();
  }
  //没有token直接去登录页面
  if(getAuthorization()==null){
    return next({path: "/login"});
  }
  const homeUrl = MenuUtil.getHomeUrl();
  //解决回退时进入首页的BUG
  if (to.path == process.env.PATH && homeUrl != "") {
    return next({ path: homeUrl });
  }
  next()
});

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐