目录
一、说在前面
1、实现
其实Vue + Vue-RouterV4 的思路也是差不多的,只是语法有些差异,而且 Vue-RouterV4 提供了更多的方法去清空路由栈,有兴趣的可以了解一下
2、权限列表
权限列表的结构,我们采用对象的结构,其中属性代表着路由表中的name,控制权限页面管理,属性值为操作权限的标识,例如C代表创建(Create
),控制操作权限管理
permission:{
'RoadAdmin':'R'
'Orderlist':'CURD'
}
二、页面权限
1、实现效果
页面权限通常有两种实现,一种是没有权限的路由就导向一个“没有权限”的页面,还有一种就是没有权限的路由是不会被创建的。这次我们要实现的是第二种效果。
2、思路和实现
(1)登录之后:后端返回权限列表,将权限列表的数据存到localStorage中,并通过vuex进行管理
login.vue
//假设我获取到数据 {'Test':'E'}
const permission = resp.data.permission //根据后端数据结构来
this.$store.commit('setPermission',permission)
store/index.js
state:{
permission:JSON.parse(localStorage.getItem('permission'))||{},
}
mutation:{
// 权限
setPermission(state,payload){
state.permission=payload
localStorage.setItem('permission',JSON.stringify(state.permission))
},
}
(2)把所有的路由分为两部分:
- 静态的——所有的角色都能够访问
- 动态的——根据角色权限访问
router/data.js
// 静态路由——所有用户都可以访问
const routes = [
{
path: "/login",
name: "Login",
component: () => import("../views/login.vue"),
},
{
path: "/",
name:'Index',
component: () => import("../views/index.vue"),
children:[
{
path: "/admin",
name: "Admin",
component: () =>
import("../views/admin/index.vue"),
},
]
}
]
//动态路由——根据权限决定是否可以访问
const dynamic_routes=[
{
path: "/parking-admin/test",
name: "Test",
component: () =>
import("../views/test/test.vue"),
},
]
router/index.js:使用静态路由创建路由实例
import Vue from "vue";
import VueRouter from "vue-router";
Vue.use(VueRouter);
import {routes} from './data'
// 静态路由
const router = new VueRouter({
routes,
});
//......省略其他逻辑
export default router
(3)utils下封装两个函数:
- 动态添加路由
- 重置路由
import { dynamic_routes } from "../router/data"
import Vue from "vue";
import VueRouter from "vue-router";
Vue.use(VueRouter);
export function addRoutes(permission,router){
// 动态添加权限路由
if(permission !=null){
// 有权限
const permission_list = permission
const allow_routes = dynamic_routes.filter((route)=>{
// 筛选出在权限列表的路由
return permission_list.hasOwnProperty(route.name)
})
// 权限路由作为index的children
allow_routes.forEach(route=>{
router.addRoute("Index",route)
})
}
}
export function resetRoutes(router){
// 清除路由栈
sessionStorage.removeItem('cached')
sessionStorage.removeItem('openedTopMenu')
sessionStorage.removeItem('topMenuActive')
let options = router.options
// 用原始数据重新new一个
let _VueRouter = new VueRouter(options)
router.matcher = _VueRouter.matcher
}
(4)登录成功后,调用动态添加权限路由的函数;退出登录(切换用户)的时候,重置路由
// 重新加载路由——动态添加
addRoutes(this.$store.state.permission,this.$router)
// 重置路由栈
resetRoutes(this.$router)
三、菜单权限
1、实现效果
只显示有权限的菜单
2、实现思路
登录成功之后,直接从后端得到拥有权限的菜单,再进行渲染等操作(正常操作就不放代码啦)
三、操作权限
1、通过自定义指令的方式
(1)指令的参数值表示所需的权限,例如用CURD
来标识(CURD
代表创建(Create
)、更新(Update
)、读(Retrieve
)和 删除(Delete
))
(2)当页面加载时,会根据当前用户在 store
中的权限信息,判断是否拥有访问当前页面的权限。如果没有权限,就移除该元素
(3)注意这里使用的是inserted,获取路由的方式是通过vode.context
main.js
Vue.directive('permission', {
inserted(el, binding, vnode) {
const value = binding.value; // 获取权限值
if( vnode.context.$route.name ){
const page_name = vnode.context.$route.name; // 获取当前路由名称
const have_permissions = store.state.permission[page_name] || ''; // 当前用户拥有的权限
if (!have_permissions.includes(value)) {
console.log(el.parentElement)
el.parentElement.removeChild(el); //不拥有该权限移除dom元素
}
}
},
})
xxx.vue
<button v-permission="'U'">修改</button> <button v-permission="'D'">删除</button>
2、通过v-if
这个就是在页面的mounted中获取到当前路由,再从权限列表中获取当前路由的操作权限,有权限的就显示,没权限的就隐藏。
// 权限
handlePermission(){
//获取当前路由的name
const currentRouteName = this.$route.name
//获取当前路由的所有操作权限
const have_permission = this.$store.state.permission[currentRouteName]
if(have_permission.includes('E')){
//记得在data中声明一下
this.exportPermisson = true
}
},
<el-button type="text" v-if="exportPermisson">导出</el-button>
3、还要一种就是表格的操作(如下图所示)
(1)如果你的操作是采用插槽的方式写入的,那依旧是可以使用上面两种方法的
(2)如果是配置的方式,那就需要将配置数组进行处理
示例如下:
其中columns 是定义在 export defalut 之前的,存储着所有表头数据
this.columns 是在data中经过处理后得到的数据
columns结构如下:
const columns=[
{
index:0,
label: '编号',
prop: 'name',
minWidth: '150px'
},
{
index:1,
label: '操作',
prop: 'operations',
isOperation:true,
minWidth: '150px',
fixed:"right",
cols: [
{
label: '编辑',
type: 'primary',
},
{
label: '删除',
type: 'danger',
}]
}
]
要在组件的mounted中调用哦
handlePermission(){
//获取当前路由的name
const currentRouteName = this.$route.name
//获取当前路由的所有操作权限
const have_permission = this.$store.state.permission[currentRouteName]
// 表格操作权限——过滤掉没有权限的操作按钮
const permissionCol = filterCol(have_permission)
this.columns= permissionCol
//这个是动态显示列操作的东西,忽略
this.checkedColumns=JSON.parse(JSON.stringify(this.columns))
},
const filterCol = (tagList)=>{
const permissionCol=columns.map(item=>{
if(item.prop==='operations'){
const permissionSubCols=item.cols.filter(operation=>{
return tagList.includes(operation.permissionTag)
})
return {
...item,
cols:permissionSubCols
}
}
else{
return item
}
})
return permissionCol
}