超级详细的权限管理实现(Vue2+Vue-RouterV3 ,附代码)

目录

一、说在前面

1、实现

2、权限列表

二、页面权限

1、实现效果

2、思路和实现

三、菜单权限

1、实现效果

2、实现思路

三、操作权限

1、通过自定义指令的方式

2、通过v-if

3、还要一种就是表格的操作(如下图所示)


一、说在前面

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
}
  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值