第一步 新建页面目录
:首先我们写我们的自己功能模块页面,需要现在page页面按照接口名的规则把目录和文件以及页面国际化的i18n文件创建好,例如我要实现/权限管理/角色管理的crud界面
-
首先先看apifox接口文档 /权限管理/角色管理 随便哪一个接口名的前两位 /auth/role
-
以/auth/role在前端pages目录下面创建页面目录以及国际化文件以及讲less样式抽取出来的index.less
第二步 配置路由
antd-admin后台管理模版给我提供了两种形式路由的配置,分别是同步路由和异步路由的配置
同步路由和异步路由的区别:
同步路由:同步路由不需要根据后端返回的路由进行筛选,会统一通过 router.addRoutes(finalRoutes);直接全部加入vue的路由组里面,虽然也可以利用权限表达式控制是否在菜单展示,但是即使不在菜单里面显示,假设有个人以前是A角色 能看到某个菜单 ,后面把A角色换成了B角色,这时候他没有菜单了,但是由于他以前记住了那个菜单的路由的path,他可以直接浏览器访问
异步路由:异步就是需要通过后端返回的该角色所拥有的路由数组将前端所有的路由筛选过滤一遍,再将筛选结果通过router.addRoutes(finalRoutes);部加入vue的路由组里面,此时不光菜单看不到,连再浏览页面url也无法访问
- antd-admin同步路由的配置在
src/router/config.js
目录里面,但是antd-admin我们所有的一级菜单都全部 如果配置同步路由,所有一级路由必须配置 path: ‘/’,这个一级路由的children,和我们以前传统的方式配置一路有不一样,如果不是antd-admin不建议这样做,应该所有一级路由和path: '/'是同级的
详细介绍看下方代码块注释
// An highlighted block
{
path: '/',
name: '首页',
component: TabsView,//使用公共带tabseView页面组件,带多页签的组件
redirect: '/login',
children: [
{
path: 'auth', //如果配置同步路由,所有一级路由必须配置 path: '/',这个一级路由的children,和我们以前传统的方式配置一路有不一样,如果不是antd-admin不建议这样做,应该所有一级路由和path: '/'是同级的
name: 'auth',
meta: {
icon: 'dashboard',//菜单的图标,优先会使用antd图标组件
authority: {
permission: 'auth', //登录用户非admin角色,就需要比较后台接口返回的用户的角色表达式
role: 'admin'// 只要登录用户包含admin角色 就不用比较上面permission表达式了,直接可以看见该菜单
},
},
component: BlankView, //所有菜单一级路由使用@/layouts/BlankView目录下面的BlankView
children: [
{
path: 'role',
name: 'role',
meta: {
page: {
closable: false,//菜单的图标,优先会使用antd图标组件
authority: {
permission: 'auth:role', //登录用户非admin角色,就需要比较后台接口返回的用户的角色表达式
role: 'admin'// 只要登录用户包含admin角色 就不用比较上面permission表达式了,直接可以看见该菜单
},
}
},
component: () => import('@/pages/auth/role/index') //配置pgaes下面新建的页面目录
}
]
}
]
}
- antd-admin异步路由的配置在
src/router/async/router.map.js
目录里面,在这里配置又有点和同步路由以及我们以前学的传统的不一样了,再异步路由配置文件里面,路由用key :value(对象形式)配置,没有children子路由数组了,父子路由是同级的了 key就是之前我们在同步路由里面的name,vlaue就是之前在同步路由里面的每个路由对象,只不过没有meta属性了,把meta属性都合并到value对象里面,详细介绍看下方代码块注释
/** *********权限管理模块**********/
auth: { //这里的key实际就是 路由的name值 这样一组key:value就代表一个路由
path: '/auth', //这里的一级路由的path就必须要加 / 和config.js同步路由配置不一样
name: 'auth', //这里的一name就是config.js的name,name和我们传统的配置路由一样 不加 / ,但是必须唯一
component: view.blank, //这里的name就是对应config.js的ncomponent,只不过这个文件抽成view对象里面引用
icon: "close",
authority: { // //这里的authority就是对应config.js的meta下面的authority对象
permission: 'sys',
role: 'admin'
},
},
role: {
path: '/auth/role',//这里的二级路由的path就必须要加/一级路由/二级路由 和config.js同步路由配置不一样
name: 'role', //这里的的name就是对应config.js的name name和我们传统的配置路由一样 不加 /
component:() => import('@/pages/auth/role'), //这里的name就是对应config.js的ncomponent
icon: "close",
authority: { // //这里的authority就是对应config.js的meta下面的authority对象
permission: 'auth:role',
role: 'admin'
},
},
/** *********权限管理模块**********/
第三步配置路由国际化
antd-admin的路由国际化在src/router/i18n.js
文件,此国际化使用实际就是对路由配置中的name进行国际化
第四步使用mock模拟后端接口返回的权限数据以及角色数据还有异步路由数据
authority.role> authority.permission,角色比较的优先级大于权限表达式的优先级,就是只要满足角色以后权限不会再去比较了,如果角色不满足才会比较权限
- 模拟角色数组 ,只要满足下面的格格式,并且调用antd-admin提供的vuex的方法
this.$store.commit('account/setRoles', roles)
,antd-admin就可以自动帮我们根据roles
数组中id
对应匹配路由数据中authority.role
的值的菜单,
let roles: [
{
id: 'ad-a',
},
{
id: 'admin',
}
]
- 模拟后端菜单表达式数组,只要满足下面的格格式,并且调用antd-admin提供的vuex的方法
this.$store.commit('account/setPermissions', permissions)
,antd-admin就可以自动帮我们根据permissions
数组中id
对应匹配路由数据中authority.permission
的值 菜单以及以及用operation
中的匹配对应页面的v-auh=的值,如果v-auth 没有的,则按钮变成灰色色禁用状态
let permissions=[
{
id: 'auth',//id为当前登录用户的校色对应的权限表达式,匹配的是路由配置里面的authority.permission,一级路由菜单目录不需要operation操作权限数据
},
{
id: 'auth:role',//id为当前登录用户的权限表达式,匹配的是路由配置里面的authority.permission,二级路由菜单目录需要operation操作权限数据
operation: ['auth:role:edit','auth:role:add'] //当前登录用户的角色所具备当前页面按钮操作,和自定义指令v-auth="`auth:role:add`" 如果这里少某个权限,页面中的这个按钮变成灰色并且不能点击
},
{
id: 'auth:admin',
operation: ['auth:admin:edit','auth:admin:add', 'auth:admin:del','auth:admin:query']
},
{
id: 'sys',
},
{
id: 'sys',
},
{
id: 'sys:sys_tenant',
operation: ['sys:sys_tenant:pages', 'sys:sys_tenant:edit', 'sys:sys_tenant:details']
},
]
- 筛选异步路由,只要数据格式满足下方的形式,就会使用router的属性值去匹配router.map.js中的key,如果匹配上,router.map.js的路由就会被addRoute添加进路由,没有则不会添加,所以也就访问不到
上面只是完成动态菜单的匹配,但是还是筛选异步路由,这样造成的情况就是菜单看不到,但是页面还能通过path url访问到
let routers: [ //必须是数组,数组只有一个 对象 ,从root开始,下面是children,和src/router/config.js中的同步路由有点类似,但是属性不一样
{
router: 'root', //router实际上就对应router.map.js中的key或者name
children: [
{
router: 'auth',//下面还有层级就追加children
icon: 'dashboard',
children: [{
router: 'role',
}]
},
{
router: 'sys',
icon: 'dashboard',
children: [{
router: 'user',
},
{
router: 'role',
}]
},
]
}
],
.