vue动态路由的使用

news/2024/7/10 3:25:29 标签: vue.js, javascript, vue

项目创建过程中经常遇到的一个需求就是权限管理,本文就我在使用动态路由的过程中进行一个总结

首先,前端想要实现对菜单的动态渲染实际上有两种操作方式

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优先级变得很高。放在异步路由之后再加载重定向,无疑是最合理且符合项目要求的。

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


http://www.niftyadmin.cn/n/1835602.html

相关文章

zip加密解密的奇怪问题

我总结的zip和unzip常用形式: zip -r -P 123456 1.zip 1.txt unzip -P 123456 -f -o -u -X 1.zip -d /tmp 通过我的验证,当你要压缩的内容只是目录,没有文件时,即使加密压缩,解密的时候,直接解密&#xff0…

阿里矢量图刷新显示异常

在vue中使用阿里矢量图遇到了刷新丢失问题 一开始我使用的是在根html中引入的方式&#xff0c; <link rel"stylesheet" href"./font/iconfont.css">在使用过程中莫名的遇到了刷新丢失问题 于是更改了新的css引入方式 main.js中新增引入 import "…

编译无效对象有什么用处?

一般情况下oracle里的无效对象的出现是因为该对象&#xff08;视图、存储过程、触发器等&#xff09;中引用的其他对象&#xff08;视图、表、存储过程、触发器等&#xff09;发生了改变&#xff0c;联动影响了当前对象当函数\包 等对象失效时,在调用函数或包时 程序就会报错,重…

RHCE有什么用?

CE 是红帽的中级认证 想考的都应该是知道。经常问考了CE 就有好工作吗 &#xff1f;一定做linux工作吗&#xff1f;我在这里说说自己的看法。 这个问题其实完全在于自己的&#xff0c; 考这个不一定能找到更好的工作。 有的公司不看这个&#xff0c; 主要是你考这个证书 学习到…

InnoDB状态信息说明

Innodb_buffer_pool_pages_data: Innodb buffer pool缓存池中包含数据的页的数目&#xff0c;包括脏页。单位是page。 Innodb_buffer_pool_pages_dirty: innodb buffer pool缓存池中脏页的数目。单位是page。 Innodb_buffer_pool_pages_flushed: innodb buffer pool缓存池中刷新…

20几岁决定男人的一生续二

第9节&#xff1a;完成三十岁前的积累&#xff0c;准备做一个成功的男人(9) 3.保险&#xff1a;保障未来 二十几岁的男人&#xff0c;也要为将来做打算&#xff0c;为不可预知的未来做打算&#xff0c;因此&#xff0c;在年轻时就要懂得规划自己的保单&#xff0c;购买适当比例…

开启Web金库:互联网业务成功之道——前言

我在2005年几乎就只做了一件事情&#xff0c;就是在亚马逊网上书店找一本书&#xff0c;我是说真的&#xff01;当时我刚刚写完了MasterList Professional&#xff0c;一款Windows下的个人任务管理软件&#xff0c;我的计划是卖掉一百万套&#xff0c;然后就可以结束编程生涯&a…

防火墙的并发及吞吐

防火墙 : 网络吞吐量 网络中的数据是由一个个数据包组成&#xff0c;防火墙对每个数据包的处理要耗费资源。吞吐量是指在不丢包的情况下单位时间内通过防火墙的数据包数量。 随着Internet的日益普及&#xff0c;内部网用户访问Internet的需求在不断增加&#xff0c;一些企…