In projects such as backend systems, the distinction between user roles and permissions is an integral part of the requirements. There are two common ways to distinguish user rights. One is that the front end requests the interface to get the user rights information configured in the background. The other is to define the permission page of each user role directly from the front end, and then generate the corresponding route. Today we’ll look at how the front end configures routing permissions.

Configure the role rights page

When configuring the routing page corresponding to the role, you can refer to the parameters of the navigation component of the front-end framework used by the project. The menu component of ELment UI is used as an example. You can configure the following parameters for Auditor, Supplier, and Business:

const appMenuitem = {
// The auditor drops down options (Routing) menu
Auditor: [
  {
    // icon: "el-icon-view", // operationLog userConfiguration
    title: "Basic configuration".index: "1".subs: [{index: "dataOverview".title: "Data Overview"}]}, {// icon: "el-icon-view",
    title: "Requirements Review".index: "2".subs: [{index: "demendManage".title: "Demand Management"}}]].// The business side drops down options and routes
Business: [
  {
    title: "Basic configuration".index: "1".subs: [{index: "demandList".title: "List of Requirements"}}]]./ / supplier
Supplier: [
  {
    title: "Demand making".index: "1".subs: [{index: "needList".title: "List of Requirements"}]}]};Copy the code

After this configuration, the permission information of all user roles is in appMenuitem. In the development of the project, we can set up pages according to the value of the configured object attribute Index (which can be agreed by the developer according to their own conventions), such as dataOverview and demendManage. As shown in figure:

Generate side menu logic (the router must be configured to run) :

<el-menu background-color="#fff" text-color="#222222" theme="dark" :default-active="onRoute" :collapse="false" router > <template v-for="(item, index) in items"> <! <template v-if="item.subs && item.subs.length > 0"> <el-submenu :index="item.index" :key="index"> <template slot="title"> <i :class="item.icon" ></i> <span>{{ item.title }}</span> </template> <el-menu-item-group> <el-menu-item v-for="(subItem, index2) in item.subs" :key="index2" :index="subItem.index" > <span>{{ subItem.title }}</span> </el-menu-item> </el-menu-item-group> </el-submenu> </template> <! - no options - > < template v - else > < el - menu - item: index = "item. The index:" key = "item. The index" > < I: class = "item. The icon" > < / I > {{ item.title }} </el-menu-item> </template> </template> </el-menu>Copy the code
    this.items = appMenuitem[userMap[this.userInfo.role]];
Copy the code

The manual configuration is done. The following is to complete the dynamic generation of the route.

Routing generation

Configure the project generic route in router.js:

let router = new Router({
routes: [{path: "/".redirect: "/home"}, {path: "/login".name: "login".component: resolve= > require([".. /views/Login.vue"], resolve)
  }
]
});
Copy the code

The home is the primary route, and the route pages configured previously are nested in the home. Let’s look at ways to generate other routes

function initRouter() {
// Login user role Auditor Business supplier
const userType = userMap[store.state.userInfo.role] || 'Auditor';
let subs = appMenuitem[userType],
  children = [];
subs = subs
  .map(c= > c["subs"])
  .forEach(sub= > {
    children = children.concat(sub);
  });
children = children.map((child, index) = > {
  if (index == 0) {
    return {
      path: ` /${child.index}`.component: resolve= >
        require([`@/views/${userType}/${child.index}.vue`], resolve)
    };
  }
  return {
    path: ` /${child.index}`.name: `${child.index}`.component: resolve= >
      require([`@/views/${userType}/${child.index}.vue`], resolve)
  };
});
// To configure the menu navigation
children.unshift({
  path: "/".redirect: children[0].path
});
// console.log(children)
return children;

}
Copy the code

You just call this method to generate a child route to home. The router’s APIaddRoutes can then be used to add routes

// Avoid repeating production dynamic routes without refreshing the page
window.hasRoutes = false;

router.beforeEach((to, from, next) = > {
// Route guard
if (to.path === "/login") {
  // Please remove the login information
  localStorage.removeItem("hasLogin");
}
let user = localStorage.getItem("hasLogin") = =null;
/ / store here. State. The userInfo. Return to the role is the background User role information role for 1 2 3 corresponding values at the front of the key value the Author...
if((user|| ! store.state.userInfo.role) && to.path ! = ="/login" ) {
  // If the login information is invalid, go to the login page
  next({ path: "/login" });
} else {
  // Get the dynamic route
  if (store.state.userInfo.role && !window.hasRoutes) {
    // window.hasroutes For simplicity, the global variable used to enter the login.vue page can also be reset to false

    // router Creates a new routing object
    let newRouter = new Router({
      routes: [{path: "/".redirect: "/home"}, {path: "/login".name: "login".component: resolve= > require([".. /views/Login.vue"], resolve)
        }
      ]
    })
    let children = initRouter();
    router.matcher = newRouter.matcher;
    // Add a route
    router.addRoutes([
      {
        path: "/home".// name: "home",
        component: resolve= > require(["@/views/Home.vue"], resolve),
        children: children
      }
    ]);
    // Avoid repetition
    window.hasRoutes = true;
    // In this case, when the actual situation exists that the login object is switched, the first route loading fails and needs to be refreshed, we manually jump to home and re-walk the logic just described
    if(from.path == '/login') {
      router.push({path:'/home'})}else{
      router.push({ path: to.path })
    }
  } 
  else{ next(); }}});Copy the code

Finally, the front-end configuration generated dynamic routing method is basically like this, this is the pit I encountered in the project, I hope to help.