路由权限

118 阅读4分钟

1. 获取后端返回的菜单权限树

通常情况下,可以通过 API 获取后端返回的权限树。例如,返回的数据结构可能如下:

js
 代码解读
复制代码
[{		"name": "dashboard",		"path": "/dashboard",		"children": [{			"name": "overview",			"path": "overview"		}]
	},
	{
		"name": "settings",
		"path": "/settings",
		"children": []
	}
]

2. 定义异步路由对象

异步路由对象可以在前端进行维护,包含所有可能的路由配置。每个路由配置中包含相应的组件引用:

js
 代码解读
复制代码
const asyncRoutes = {
  dashboard: {
    path: '/dashboard',
    name: 'dashboard',
    component: () => import('@/views/Dashboard.vue'),
    children: {
      overview: {
        path: 'overview',
        name: 'overview',
        component: () => import('@/views/DashboardOverview.vue'),
      },
    },
  },
  settings: {
    path: '/settings',
    name: 'settings',
    component: () => import('@/views/Settings.vue'),
  },
}

3. 根据权限树匹配异步路由

根据后端返回的权限树,递归遍历并匹配异步路由对象,动态生成路由配置。你可以通过递归函数将后端数据与前端路由进行匹配。

js
 代码解读
复制代码
// 递归方法将权限树与异步路由对象匹配
function generateRoutes(permissionTree, asyncRoutes) {
  const matchedRoutes = []

  permissionTree.forEach((node) => {
    const route = asyncRoutes[node.name]

    if (route) {
      const newRoute = { ...route }

      // 如果有子路由,递归处理
      if (node.children && node.children.length > 0) {
        newRoute.children = generateRoutes(node.children, route.children || {})
      }

      matchedRoutes.push(newRoute)
    }
  })

  return matchedRoutes
}

要实现 Vue Router 的动态路由加载,并根据后端返回的菜单权限树动态生成路由,需要进行以下步骤:

步骤概述:

  1. 获取后端返回的菜单权限树:后端会返回一个包含菜单权限的树结构,通常是通过 API 获取。
  2. 定义异步路由对象:在前端维护一个包含所有可能路由配置的异步路由对象。
  3. 根据权限匹配路由:遍历后端返回的菜单权限树,动态匹配异步路由对象中的组件。
  4. 动态添加路由:使用 Vue Router 的 addRoute 方法将匹配的路由动态添加到 Vue Router 实例中。

详细步骤实现:

1. 获取后端返回的菜单权限树

通常情况下,可以通过 API 获取后端返回的权限树。例如,返回的数据结构可能如下:

css
 代码解读
复制代码
json
复制代码
[  {    "name": "dashboard",    "path": "/dashboard",    "children": [      {        "name": "overview",        "path": "overview"      }    ]
  },
  {
    "name": "settings",
    "path": "/settings",
    "children": []
  }
]

2. 定义异步路由对象

异步路由对象可以在前端进行维护,包含所有可能的路由配置。每个路由配置中包含相应的组件引用:

css
 代码解读
复制代码
javascript
复制代码
const asyncRoutes = {
  dashboard: {
    path: '/dashboard',
    name: 'dashboard',
    component: () => import('@/views/Dashboard.vue'),
    children: {
      overview: {
        path: 'overview',
        name: 'overview',
        component: () => import('@/views/DashboardOverview.vue'),
      }
    }
  },
  settings: {
    path: '/settings',
    name: 'settings',
    component: () => import('@/views/Settings.vue')
  }
};

3. 根据权限树匹配异步路由

根据后端返回的权限树,递归遍历并匹配异步路由对象,动态生成路由配置。你可以通过递归函数将后端数据与前端路由进行匹配。

ini
 代码解读
复制代码
javascript
复制代码
// 递归方法将权限树与异步路由对象匹配
function generateRoutes(permissionTree, asyncRoutes) {
  const matchedRoutes = [];

  permissionTree.forEach(node => {
    const route = asyncRoutes[node.name];

    if (route) {
      const newRoute = { ...route };
      
      // 如果有子路由,递归处理
      if (node.children && node.children.length > 0) {
        newRoute.children = generateRoutes(node.children, route.children || {});
      }

      matchedRoutes.push(newRoute);
    }
  });

  return matchedRoutes;
}

5. 在导航守卫中处理动态路由

为了确保动态路由在用户登录后或者权限加载完成后生效,你可以在 Vue Router 的全局守卫中动态加载路由

js
 代码解读
复制代码
router.beforeEach(async (to, from, next) => {
  if (!router.hasAddedRoutes) {
    // 检查是否已加载动态路由
    const permissionTree = await fetchPermissionTree() // 获取菜单权限树
    const dynamicRoutes = generateRoutes(permissionTree, asyncRoutes)

    dynamicRoutes.forEach((route) => {
      router.addRoute(route)
    })

    router.hasAddedRoutes = true // 标记已加载动态路由
    next({ ...to, replace: true }) // 确保当前路由已加载完成
  } else {
    next() // 如果已经加载动态路由,直接进行导航
  }
})

总结

  1. 通过后端返回的菜单权限树,可以根据用户的权限动态加载路由。

  2. 在前端维护一个包含所有可能路由的异步路由对象,并使用递归函数匹配权限树和异步路由。

  3. 动态地通过 router.addRoute 添加路由,实现根据用户权限动态生成菜单的功能。

  4. 为确保动态路由生效,可以在导航守卫中动态加载路由。

作者:Healer918
链接:juejin.cn/post/742751…
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。