vue动态路由的使用

2 篇文章 0 订阅
2 篇文章 0 订阅
项目创建过程中经常遇到的一个需求就是权限管理,本文就我在使用动态路由的过程中进行一个总结
首先,前端想要实现对菜单的动态渲染实际上有两种操作方式

1.前端还是书写静态路由表,根据后端传来的code利用v-if去判断渲染菜单项
实际这种使用方式并不可取,因为不方便后期维护。
2.前端只写没有权限控制的login,register, 404 页面的路由,其余路由则是根据后端传过来的,拼接入路由表。

这里我在项目中使用的第二种方法

首先,我们要先理解动态路由表的请求和添加都是发生在路由守卫里边的。
不废话直接上代码

const whiteList = ["/login", "/register"];  // 白名单,不需要token也可以进入的页面
router.beforeEach(async (to, from, next) => {
  NProgress.start();
  // document.title = to.meta.title;
  // 获取用户token,用来判断当前用户是否登录
  const hasToken = getToken();
  if (hasToken) {
    if (whiteList.indexOf(to.path) !== -1) {
      next();
      NProgress.done();
    } else {
      // 用来获取后台拿到的路由
      const route = await store.getters.addRouters;
      // console.log("to.path", to.path, route);
      if (route && route.length > 0) {
        if (to.path === "/") {
          next("/console");
        }
        next();
        NProgress.done();
      } else {
        store.dispatch("queryMenuList").then(({ servers }) => {
          // console.log("拿到的初始路由结构", servers);
          filterAsyncRouter(servers);
          const menus = store.getters.addRouters;
          const routerMap = newRouter(menus);
          for (let key in routerMap) {
            router.addRoute("layout", routerMap[key]);
          }
          router.addRoute({ // 这里是对404页面的一个重定向
            path: "*",
            redirect: "/404",
            hidden: true,
          });
          let homeChildren = router.options.routes[2];
          // homeChildren = menus
          homeChildren["children"] = routerMap;
          // console.log("最终的", menus);
          next({
            ...to,
            replace: true,
          }); // hack方法 确保addRoutes已完成 ,set the replace: true so the navigation will not leave a history record
          NProgress.done();
        });
      }
      next();
      NProgress.done();
    }
  } else {
    if (whiteList.indexOf(to.path) !== -1) {
      // 需要跳转的路由是否是whiteList中的路由,若是,则直接条状
      next();
    } else {
      // 需要跳转的路由不是whiteList中的路由,直接跳转到登录页
      // console.log("redirect",to.fullPath)
      next("/login?redirect=" + to.fullPath);
      // 结束精度条
      NProgress.done();
    }
  }
});

store.dispatch(“queryMenuList”)这里是我在vuex中定义的请求动态路由表的方法;

filterAsyncRouter方法

从后端直接请求过来的动态路由表往往是不能直接使用的,我们需要把他的数据结构转换成我们前端路由表的结构。并且把组件对应到路由中去。

const _import = require("@/router/_import_" + process.env.NODE_ENV); //获取组件的方法
function filterAsyncRouter(asyncRouterMap) {
  // 过滤动态路由
  const newArr = [];
  asyncRouterMap.forEach((item) => {
    const component = _import(item.component);
    // console.log("component", component, item.component ,item.path);
    let routerTemplate = {
      name: item.serverName,
      id: item.id,
      path: item.path,
      component,
    };
    if (item.children && item.children.length > 0) {
      routerTemplate.children = filterRouter(item.children);
    }
    newArr.push(routerTemplate);
  });
  return newArr;
}

_import是引入组件的方法,具体作用就是把组件对应到路由表中去

module.exports = (file) => {
  // console.log("传进来的组件地址", file);
  var a = true;
  try {
    // (resolve) => require("@/views/" + file + "/index.vue", resolve)
    return require("@/views/" + file + "/index.vue").default;
  } catch (e) {
    a = false;
  }
  if (a) {
    // console.log("要找的地址2", "@/views/" + file + "/index.vue");
    return require("@/views/" + file + "/index.vue").default;
  }
};
拿到合格的路由之后我们就可以把路由放到项目路由表中去了

先看一下我们的静态路由

// 配置项目中没有涉及权限的公共路由
export const constantRoutes = [
  {
    path: "/login", // 登陆
    component: login,
  },
  {
    path: "/register", // 登陆
    component: register,
  },
  {
    path: "/",
    name: "layout",
    component: layout,
    children: [],
  },
  {
    path: "/404",
    name: "notFound",
    component: notFound,
  },
  // {
  //   path: "*",
  //   redirect: "/404",
  // },
];

我使用的是vue-router是@3.5.2版本所以添加路由使用的是addRoute方法,低版本的vue-router可以尝试addRoutes方法。(ps:addRoute方法需要一个对象一个对象添加,因此下边使用了for循环,addrouters方法可以直接把数组添加到路由表中)

for (let key in routerMap) {
            router.addRoute("layout", routerMap[key]);
    }
router.addRoute({
            path: "*",
            redirect: "/404",
            hidden: true,
  });  

或者:addRoute可以选则路由插入位置。

router.addRoutes(menus.concat([{
              path: '*',
              redirect: '/404',
              hidden: true
            }]));

给大家解释一下上边对404的疑问,之所以静态路由表把重定向去掉,是因为使用动态路由是异步加载,如果把重定向放静态路由就会导致404优先级变得很高。放在异步路由之后再加载重定向,无疑是最合理且符合项目要求的。

到这里异步路由就加载完毕了,可以正常使用。后边就是对多级菜单的动态渲染了,如果有需求可以参考另一篇文章
对多级菜单的动态渲染

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值