vue权限功能的实现

136 阅读1分钟

前言

权限功能是我们经常会碰到的需求,最近也是有做一套权限系统,在此做个总结

设计

权限一般分为页面路由权限和按钮级权限。

  1. 页面路由权限 在项目中可以和后端约定好账号角色,为每个角色分配不同的权限,然后通过全局的路由守卫来判断拦截即可

  2. 按钮级权限 同样也和后端约定好按钮权限名称,我用的是'system:page1:add'这样的形式来描述系统的按钮位置,然后通过自定义指令判断一下即可

实现

  1. 页面路由权限

路由如果需要权限识别的话,首先要设置meta属性,用roles字段来表示可以访问该页面的角色

const routes = [
  {
    path: "/page1",
    name: "page1",
    component: () =>
      import(
        /* webpackChunkName: "Page1" */ "@/views/page1.vue"
      ),
    meta: {
      roles: ['admin', 'manager']
    }
  }
]

接着通过路由守卫来判断是否有权限,没有权限则重定向到无权限页面

const router = createRouter({
  history: createWebHashHistory(),
  routes,
});

router.beforeEach((to, from, next) => {
  const roles = store.getters && store.getters.roles
  if (to.meta.roles) {
    const hasPermission = to.meta.roles.some((el) => {
      return roles.includes(el)
    })
    if (hasPermission) {
      next()
    } else {
      next({ path: '/404' })
    }
  } else {
    next()
  }
})
  1. 按钮级权限

设计一个自定义指令:

import store from '@/store'

export default {
  mounted (el, binding) {
    const { value } = binding
    const all_permission = "*:*:*";
    const permissions = store.getters && store.getters.permissions

    if (value && value instanceof Array && value.length > 0) {
      const permissionFlag = value

      const hasPermissions = permissions.some(permission => {
        console.log(all_permission, permission, permissionFlag)
        return all_permission === permission || permissionFlag.includes(permission)
      })

      if (!hasPermissions) {
        el.parentNode && el.parentNode.removeChild(el)
      }
    } else {
      throw new Error(`请设置操作权限标签值`)
    }
  }
}

全局注册自定义指令

import hasPermi from './hasPermi'

const directives = {
  hasPermi
}

export default {
  install(app) {
    Object.keys(directives).forEach((key) => {
      app.directive(key, directives[key])
    });
  }
}
import directives from '@/directives/index.js'

const app = createApp(App)

app.use(directives).use(router).use(store).mount('#app')

使用方式

<template>
  111
  <h1 v-hasPermi="['system:page1:title']">wefrgty</h1>
</template>

<script>
export default {

}
</script>

<style>

</style>