系统管理的按钮权限和菜单权限该如何做

本文介绍如何在Vue3中实现按钮级和菜单级权限管理,包括使用全局变量和自定义指令的方法,以及如何通过路由守卫确保用户只能访问其被授权的页面。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

按钮权限

1.使用vue3的全局变量 

main.js

//引入后端接口返回的当前用户拥有的权限列表
import { getAuthList } from "@/utils/userInfo.ts";

const $permission = (value) => {
  // 获取用户所有的权限
  const permissions = getAuthList();  
  // 判断传递进来的按钮权限,是否存在
  if (value) {
    let hasPermission = true;
    value.forEach((item) => {
      // 判断传递进来的按钮权限字段,是否存在当前用户的permissions
      hasPermission = permissions.some(i => i.url === item) && hasPermission;
    });
    return hasPermission;
  }
};

app.config.globalProperties.$permission = $permission;


//使用
<el-button v-if="$permission(['maintainPlanEdit'])">编辑</el-button>

2.使用自定义指令 

directives.js

import { getUserTotalAuthInfo } from "@/utils/userInfo.js";

const directivePlugin = {
  install(app) {
    app.directive("menu", {
      mounted(el, binding) {
        // value按钮上的权限
        const { value } = binding;
        // 获取用户所有的权限
        const permissions = getUserTotalAuthInfo();
        // 判断传递进来的按钮权限,是否存在
        if (value) {
          // 判断传递进来的按钮权限字段,是否存在当前用户的permissions
          const hasPermission = permissions.includes(value);
          if (!hasPermission) { // 没有权限时,影藏
            el.style.display = 'none';
          }
        }
      },
    });
  },
};
export default directivePlugin;


main.js

import directivePlugin from "@/directives";

const app = createApp(App);
app.use(directivePlugin)
   .mount("#app");


//使用

<el-button v-menu="'verifyCountryChart'"> 结果统计 </el-button>

菜单权限

用户登录后,将后台返回的当前用户所拥有的菜单权限存到本地,在路由前置守卫中判断,用户要去的路由位置,判断这些路由是否用户有权限去,有则放行,无则跳到403无权限页面

utils/permission.js

import router from '@/router'
import NProgress from 'nprogress' // 进度条
import 'nprogress/nprogress.css' // 进度条样式
import getPageTitle from '@/utils/getPageTitle'
import { isLogin } from '@/utils/userInfo'
import { geMenuList } from "@/utils/userInfo";
import { reactive } from 'vue'
let menuList = reactive({
  list:[]
})
console.log(menuList);

NProgress.configure({ showSpinner: false }) // 进度条配置

const whiteList = ['/login'] // 白名单列表

router.beforeEach((to, from, next) => {
  console.log(to.path);

  // 进度条开始
  NProgress.start()

  // 设置页面标题
  document.title = getPageTitle(to.meta.title)

  if (isLogin()) {
    //登录后获取后台返回的菜单列表(select 为1 表示 当前用户拥有此菜单权限)
     menuList.list = geMenuList()?.filter(item => item.select === 1);
    switch (to.path) {//判断用户要去哪个路由地址
      case '/login'://如果已登录  去登录页则改为去首页
        next('/')
        break;
      default:
        if (to.path === '/403' || to.path === '/404' || to.path === '/changeTheme' || to.path === '/maintainPlanAdd' || to.path === '/patrolPlanAdd') {
          next()//如果去这几个页面则放行
        } else if(to.path ==='/'){         
          next(menuList.list?.[0].url) //如果去首页 则改为去后台返回的第一个菜单
        }
        else {
          const isMenu = menuList.list?.some(i => i.url === to.path)
          // console.log(isMenu);
          if (isMenu) {   //如果去其他路由  判断这些路由是否用户有权限去
            next()
          } else {
            next('/403')
          }
        }
        break;
    }
  } else {
    //  没有token
    if (whiteList.indexOf(to.path) !== -1) {
      // 如果在白名单里,就放行=
      next()
    } else {
      // 如果不在白名单里,就重定向到登录页面
      next(`/login`)
      NProgress.done()
    }
  }
})

router.afterEach(() => {
  // 进度条结束
  NProgress.done()
})

 在main.js中引入

main.js

import '@/utils/permission'

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值