动态路由的实现
vue3动态路由的几种实现思路
·
动态路由
动态路由通俗点来讲就是,同一个系统,每个人登录上去,所看到的页面菜单是不同的,根据每个人的权限去分配页面。
后台的设计思想
后台的话会有以下几个表单:
用户表(所有用户的信息);
角色表(超级管理员,管理员,总裁…);
关系表(记录哪个角色拥有哪个权限);
权限表(也就是菜单表);
每一个用户都会给他分配一个角色,这个角色能不能去查看这个菜单
前端实现
一般使用方法三的情况比较多
方法一
把所有对应菜单的路由都写进去,把所有的路由写死
弊端:当用户通过url进入的时候,页面也会取显示
方法二
不同的角色注册不同的路由
例如:
superadimin:[{},{},{}]
admin:[{},{}],
user:[{}]…
登录->userInfo->role.name(角色)->动态的加载数组[]->main.routers
弊端:
新增角色时,需要修改前端代码,重新进行部署
方法三
根据菜单动态的生成路由映射
菜单->url->路由->path->component
例:角色管理->路径/mian/role->path->component
此时的component一个数组routes,添加到main childern里面
此时的动态生成也有两种方案:
- 菜单中就有加载组件的名称
1.1 返回就有component:Role.vue(此时前后端名称/路径必须保持一致) - 菜单中只有url
2.1 前端代码中有各自的映射关系:path1->component1;path2->component2…
具体代码实现
可以写在router里面,但是此时这个项目建议写在store里面
store部分总共分为两部分:
- 用户的菜单映射到路由上面
- 将routes添加到router.main.children
由于映射的代码比较复杂,所以在unils/map-menus.ts文件进行写相关逻辑
import { RouteRecordRaw } from 'vue-router'
export function mapMenusToRoutes(userMenus: any[]): RouteRecordRaw[] {
const routes: RouteRecordRaw[] = []
// 1.先去加载默认所有的routes
const allRoutes: RouteRecordRaw[] = []
//require.context('../router/main')webpack的函数,true是否进行递归:如果main文件夹下面还有文件夹就是写为true;如果main下面没有文件夹的情况下false,第三个参数正则表达式:匹配我们找到的文件
//在../router/main路径下去匹配.ts后缀的文件
const routesFiles = require.context('../router/main', true, /\.ts/)
//routesFiles.keys()拿到的式所有的文件的路由,是webpack特殊的函数,固定的写法
routesFiles.keys().forEach((key) => {
//通过.进行切割,拿到.后面的路径
const route = require('../router/main' + key.split('.')[1])
allRoutes.push(route.default)
})
// 2.根据菜单获取需要添加的routes
//通过递归函数进行对菜单的获取
// type === 1 -> children-> type===1
//type === 2 -> url -> route
const _recurseGetRoute = (menus: any[]) => {
for (const menu of menus) {
//需要映射的路由
if (menu.type === 2) {
// find只会找到一个,filter只要符合条件可以找到很多个
const route = allRoutes.find((route) => route.path === menu.url)
if (route) routes.push(route)
} else {
_recurseGetRoute(menu.children)
}
}
}
_recurseGetRoute(userMenus)
return routes
}
store中相关的代码:
// userMenus=>routes,由于映射比较复杂,所以写在了utils/map-menus.ts文件里面
const routes = mapMenusToRoutes(userMenus)
console.log(routes)
//将routes添加到router.main.children
routes.forEach((route) => {
router.addRoute('main', route)
})
添加相关的点击事件
const handleItemClick = (item: any) => {
console.log(item.url)
router.push({
path: item.url ?? '/not-found'
})
}
更多推荐
已为社区贡献2条内容
所有评论(0)