SoFunction
Updated on 2025-04-14

The implementation of permission control and dynamic routing of Vue background management system

Permission control is an indispensable part when developing a background management system. This article will introduce in detail how to use Vue to generate routes dynamically according to different roles, thereby controlling user access rights.

Step 1: Basic routing configuration

First, we need to configure basic routes, which are shared by all users, such as login pages and 404 pages.

const allRoutes = [
  // Basic routing  {
    path: '/',
    name: 'login',
    component: () => import("@/views/")
  },
  {
    path: '/404',
    name: '404',
    component: () => import('@/views/Error/')
  },
  // Dynamic routing container (content after login)  {
    path: '/layout',
    name: 'layout',
    component: () => import('@/Layout/'),
    children: []
  },
]

Step 2: Complete routing data

Next, create an array containing all possible routes. This array will be used to compare the permission data returned by the backend to filter out the routes that the current user has permission to access.

// All routesconst totalRoute = [
  {
    path: '/',
    name: 'login',
    component: () => import("@/views/")
  },
  {
    path: '/404',
    name: '404',
    component: () => import('@/views/Error/')
  },
  {
    path: '/layout',
    name: 'layout',
    component: () => import('@/Layout/'),
  },
  {
    path: '/home',
    name: 'front page',
    id: 1,
    pid: 0,
  },
  {
    id: 2,
    pid: 0,
    redirect: null,
    path: '/comp',
    name: 'Outpatient',
    children: [{
      id: 3,
      pid: 2,
      redirect: null,
      component: () => import('@/views/'),
      path: "/pay",
      name: "Outpatient payment record",
    },{
      id: 4,
      pid: 2,
      redirect: null,
      component: () => import('@/views/'),
      path: "/reservation",
      name: "Appointment Record",
    }]
  },
  { 
    id: 8,
    pid: 0,
    path: '/hospital',
    name: 'Hospital',
    children: [{
      id: 9,
      pid: 8,
      redirect: null,
      component: () => import('@/views/'),
      path: "/hospitalpay",
      name: "Hospital payment record",
    },{
      id: 10,
      pid: 8,
      redirect: null,
      component: () => import('@/views/'),
      path: "/room",
      name: "Room Management",
    },{
      id: 11,
      pid: 8,
      redirect: null,
      component: () => import('@/views/'),
      path: "/inpatient",
      name: "Inpatient",
    }]
  }
];

Step 3: Simulate backend permission data

For demonstration, we use simulated data to represent permission information returned by the backend.

Then there is the data returned by the backend interface, so I will use fake data instead. The basic routing and false data should be consistent. Fake data is dynamic routing (which will change)

// Dynamic accessconst dynamicRouteConfigs = [
  // Dynamic routing container (content after login)  {
    path: '/home',
    name: 'front page',
    id: 1,
    pid: 0,
  },
  {
    id: 2,
    pid: 0,
    redirect: null,
    path: '/comp',
    name: 'Outpatient',
    children: [{
      id: 3,
      pid: 2,
      redirect: null,
      path: "/pay",
      name: "Outpatient payment record",
    },{
      id: 4,
      pid: 2,
      redirect: null,
      path: "/reservation",
      name: "Appointment Record",
    }]
  },
  { 
    id: 8,
    pid: 0,
    path: '/hospital',
    name: 'Hospital',
    children: [{
      id: 9,
      pid: 8,
      redirect: null,
      path: "/hospitalpay",
      name: "Hospital payment record",
    },{
      id: 10,
      pid: 8,
      redirect: null,
      path: "/room",
      name: "Room Management",
    },{
      id: 11,
      pid: 8,
      redirect: null,
      path: "/inpatient",
      name: "Inpatient",
    }]
  },
  {
    id: 12,
    pid: 0,
    redirect: null,
    path: '/userinfor',
    name: 'User Management',
    children: [{
      id: 13,
      pid: 12,
      redirect: null,
      path: "/user",
      name: "User Management",
    },{
      id: 14,
      pid: 12,
      redirect: null,
      path: "/role",
      name: "Role Management",
    },{
      id: 15,
      pid: 12,
      redirect: null,
      path: "/admin",
      name: "Administrator Management",
    },{
      id: 27,
      pid: 12,
      redirect: null,
      path: "/visit",
      name: "Medical Card",
    }]
  },
  {
    id: 16,
    pid: 0,
    path: '/department',
    name: 'Department Management',
    children: [{
      id: 24,
      pid: 16,
      redirect: null,
      path: "/departments",
      name: "Department Management",
    }]
  },
  {
    id: 17,
    pid: 0,
    path: '/hospitals',
    name: 'Hospital Information',
    redirect: null,
    children: [{
      id: 18,
      pid: 17,
      redirect: null,
      path: "/hospitalList",
      name: "Hospital Information",
    },{
      id: 19,
      pid: 17,
      redirect: null,
      path: "/doctor",
      name: "Doctor Management",
    },{
      id: 20,
      pid: 17,
      redirect: null,
      path: "/scheduling",
      name: "Doctor Schedule Management",
    },{
      id: 21,
      pid: 17,
      redirect: null,
      path: "/label",
      name: "Tag management",
    },{
      id: 22,
      pid: 17,
      redirect: null,
      path: "/drug",
      name: "Drug Management",
    },
    {
      id: 23,
      pid: 17,
      redirect: null,
      path: "/physical",
      name: "Physical Examination Management",
    },{
      id: 26,
      pid: 17,
      redirect: null,
      path: "/trends",
      name: "Hospital News",
    }]
  }
];

Step 4: Create a routing instance

Use Vue Router to create a routing instance and initialize the registered underlying route.

// Create a routing instanceconst router = createRouter({
  history: createWebHistory(.BASE_URL),
  routes: allRoutes
})

Step 5: Filter the matching routes

Write a function to filter out matching routes. This function will traverse the permission data returned by the backend and the complete routing data, find the matching routes and add components.

  • Then make a change judgment, and by traversing the two arrays, and when the name or path of the two are the same, put it into a new array.
  • Then declare a variable equal to component, which is to add the component component component of the basic route
const filterRoutes = (dynamicRouteConfigs, totalRoute) => {
  // Print dynamic routing configuration  ('Dynamic Routing', dynamicRouteConfigs);
  // Print total route  ('Basic Routing', totalRoute);
  // Define a recursive function findMatchedRoute, which is used to find matching target routes in route arrays  const findMatchedRoute = (routes, target) => {
    // traverse the route array    for (const route of routes) {
      // If the route name is in the exclusion list, skip      if (['404', 'home'].includes()) continue;
      // If the route name or path matches the target, return the route      if ( ===  ||  === ) {
        return route;
      }
      // If the current route has a subroutine, recursively look up the matching subroutine      if () {
        const matchedChild = findMatchedRoute(, target);
        // If a matching subroutine is found, return        if (matchedChild) return matchedChild;
      }
    }
    // If no matching route is found, return null    return null;
  };
  // Define a function mergeRoutes to merge source routes and match routes  const mergeRoutes = (source, target) => {
    // Return a new routing object, containing all attributes of the source route, and component attributes that match the route    return {
      ...source,
      component: ,
      // If the source route has a subroutine, recursively merge the subroutine      children:  ? (child => mergeRoutes(child, findMatchedRoute([target], child) || {})) : undefined,
      // Other possible contents can be merged here, such as meta attributes    };
  };
  // Map dynamic routing configurations to match and merge each route  const result = dynamicRouteConfigs
    .map(route => {
      // Find matching routes      const matchedRoute = findMatchedRoute(totalRoute, route);
      // Print matching routes      (matchedRoute);
      // If a matching route is found, merge the route, otherwise return null      return matchedRoute 
        ? mergeRoutes(route, matchedRoute)
        : null;
    })
    // Filter out the null value in the result    .filter(route => route !== null);
  // Print the filtered route array  ('Filtered route array:', result);
  // Return the filtered route array  return result;
};

Step 6: Dynamically add routes

Write a function to dynamically add filtered routes to the underlying routelayoutIn the container.

Then the background control route is completed. The main thing is the same as that section of control, both of which require a basic routing array. After we compare and filter the array, we need to add the filtered array to the route. The logic is the same, just clear the logic.

It’s just that the interfaces that control routing in front and back ends are different.

// Dynamically add routes to layoutconst addDynamicRoutes = (roles) => {
  // Clear existing dynamic routes  const layout = ().find(r =>  === 'layout')
  (child => {
    ()
  })
  // Filter and add new routes  const allowedRoutes = filterRoutes(dynamicRouteConfigs, allRoutes); 
  (route => { ('layout', route); });
  (allowedRoutes);
  ('menuPath',(allowedRoutes));//Stored filtered dynamic route  // Make sure 404 is finally processed  ({ 
    path: '/:pathMatch(.*)*',
    redirect: '/404'
  })
}

Step 7: Store and render menus

Store the filtered routes in the session storage and render them on the menu page.

Through the above steps, we have completed the settings of permission control and dynamic routing based on Vue. Users of different roles will see different menus and pages, realizing refined management of permissions.

Finally, the route navigation guard will be OK.

//Router Guard Modification Part (router/)(async (to, from, next) => {
  const store = loginStore()
  const isLogin = !!
  // Not logged in status processing  if (!isLogin) {
    return  === '/' ? next() : next('/')
  }
  // Redirect when logged in but accessing the login page  if ( === '/') {
    return next('/home')
  }
  // Dynamic routing loading logic  if (!) {
    try {
      // Get saved role information directly from the store      const userRoles = ;
      // If the role information does not exist, an error will be thrown      if (!userRoles ||  === 0) {
        throw new Error('User role information not obtained')
      }
      // Add dynamic routing      addDynamicRoutes(dynamicRouteConfigs)
      // Print after adding the route      ('Current all routes:', ().map(r => ))
      // Update load status      (true)
      // Use replace to avoid repeated history recording      return next({ ...to, replace: true })
    } catch (error) {
      ('Route loading failed:', error)
      // Clear the user status and jump to the login page      store.$reset()
      return next('/')
    }
  }
  next();
})

Summarize

This article introduces how to use Vue and Vue Router to implement permission control of the backend management system. By dynamically generating routes, we can flexibly control page access rights based on the user's role, improving the security and user experience of the system.

This is the article about the implementation of permission control and dynamic routing of Vue backend management system. For more related contents of Vue permission control and dynamic routing, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!