昨天我们讲解了vue3自定义指令
这里可以先定义2个实现前端按钮级别权限的实现。
v-hasPermi, v-hasRole这2个指令,来实现是否有对应的权限。
一、自定义指令实现前端按钮级别权限
首先在@/src/directive这个目录下新建index.js,然后新建permission文件夹,在permission文件夹下新建2个文件,
一个是haspermi.js,一个是hasrole.js。
directive目录下用于项目存放自定义指令。这个目录下的index.js主要是用于注册这些指令的,在main.js中引入他直接全部注册,不用在main.js中单独写一个一个注册。
hasPermi.js
/**
* v-hasPermi 操作权限处理
* Copyright (c) 2019 ruoyi
*/
import useUserStore from '@/stores/user'
export default {
mounted(el, binding, vnode) {
const { value } = binding
const all_permission = "*:*:*";
const permissions = useUserStore().permissions
if (value && value instanceof Array && value.length > 0) {
const permissionFlag = value
const hasPermissions = permissions.some(permission => {
return all_permission === permission || permissionFlag.includes(permission)
})
if (!hasPermissions) {
el.parentNode && el.parentNode.removeChild(el)
}
} else {
throw new Error(`请设置操作权限标签值`)
}
}
}
hasRole.js
/**
* v-hasRole 角色权限处理
* Copyright (c) 2019 ruoyi
*/
import useUserStore from '@/stores/user'
export default {
mounted(el, binding, vnode) {
const { value } = binding
const super_admin = "admin";
const roles = useUserStore().roles
if (value && value instanceof Array && value.length > 0) {
const roleFlag = value
const hasRole = roles.some(role => {
return super_admin === role || roleFlag.includes(role)
})
if (!hasRole) {
el.parentNode && el.parentNode.removeChild(el)
}
} else {
throw new Error(`请设置角色权限标签值`)
}
}
}
directive目录下的index.js
import hasRole from './permission/hasRole'
import hasPermi from './permission/hasPermi'
import copyText from './common/copyText'
export default function directive(app){
app.directive('hasRole', hasRole)
app.directive('hasPermi', hasPermi)
app.directive('copyText', copyText)
}
在项目的main.js注册全部指令
// 注册指令,24行48行。
import directive from './directive'
directive(app);
下面是完整的main.js文件
import { createApp } from 'vue'
import App from './App.vue'
import Cookies from 'js-cookie'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import locale from 'element-plus/es/locale/lang/zh-cn'
import * as ElIcons from '@element-plus/icons-vue'
import Print from 'vue3-print-nb';
import '@/assets/styles/index.scss' // global css
import pinia from './stores'
import router from './router'
// svg图标
import 'virtual:svg-icons-register'
import SvgIcon from '@/components/SvgIcon'
// 注册指令
import plugins from './plugins' // plugins
import directive from './directive'
import './permission' // permission control
import { useDict } from '@/utils/dict'
import { parseTime, addDateRange, handleTree, resetForm } from '@/utils/ruoyi'
//require('./mock');
const app = createApp(App)
console.log(app.config);
console.log(import.meta.env.VITE_APP_BASE_API, '环境')
// 全局方法挂载
app.config.globalProperties.useDict = useDict;
app.config.globalProperties.parseTime = parseTime;
app.config.globalProperties.resetForm = resetForm;
app.config.globalProperties.addDateRange = addDateRange;
app.config.globalProperties.handleTree = handleTree;
app.use(router)
app.use(pinia)
app.use(Print);
app.use(plugins)
directive(app)
for (const name in ElIcons){
app.component(name, ElIcons[name]);
}
app.component('svg-icon', SvgIcon);
// 使用element-plus 并且设置全局的大小
app.use(ElementPlus, {
locale: locale,
// 支持 large、default、small
size: Cookies.get('size') || 'default'
})
app.mount('#app');
前端页面上使用案例
使用权限字符串 v-hasPermi
// 单个
<el-button v-hasPermi="['system:user:add']">存在权限字符串才能看到</el-button>
// 多个
<el-button v-hasPermi="['system:user:add', 'system:user:edit']">包含权限字符串才能看到</el-button>
使用角色字符串 v-hasRole
// 单个
<el-button v-hasRole="['admin']">管理员才能看到</el-button>
// 多个
<el-button v-hasRole="['role1', 'role2']">包含角色才能看到</el-button>
提示(这个可以不用,如果使用则需要utils下的permisson.js文件)
在某些情况下,它是不适合使用v-hasPermi,如元素标签组件,只能通过手动设置v-if。 可以使用全局权限判断函数,用法和指令 v-hasPermi 类似。
<template>
<el-tabs>
<el-tab-pane v-if="checkPermi(['system:user:add'])" label="用户管理" name="user">用户管理</el-tab-pane>
<el-tab-pane v-if="checkPermi(['system:user:add', 'system:user:edit'])" label="参数管理" name="menu">参数管理</el-tab-pane>
<el-tab-pane v-if="checkRole(['admin'])" label="角色管理" name="role">角色管理</el-tab-pane>
<el-tab-pane v-if="checkRole(['admin','common'])" label="定时任务" name="job">定时任务</el-tab-pane>
</el-tabs>
</template>
<script>
import { checkPermi, checkRole } from "@/utils/permission"; // 权限判断函数
export default{
methods: {
checkPermi,
checkRole
}
}
</script>
三、这个是utils目录下的permission.js文件(可以不用)
permission.js
import useUserStore from '@/stores/user'
/**
* 字符权限校验
* @param {Array} value 校验值
* @returns {Boolean}
*/
export function checkPermi(value) {
if (value && value instanceof Array && value.length > 0) {
const permissions = useUserStore.permissions
const permissionDatas = value
const all_permission = "*:*:*";
const hasPermission = permissions.some(permission => {
return all_permission === permission || permissionDatas.includes(permission)
})
return hasPermission;
} else {
console.error(`need roles! Like checkPermi="['system:user:add','system:user:edit']"`)
return false
}
}
/**
* 角色权限校验
* @param {Array} value 校验值
* @returns {Boolean}
*/
export function checkRole(value) {
if (value && value instanceof Array && value.length > 0) {
const roles = useUserStore.roles
const permissionRoles = value
const super_admin = "admin";
const hasRole = roles.some(role => {
return super_admin === role || permissionRoles.includes(role)
})
return hasRole;
} else {
console.error(`need roles! Like checkRole="['admin','editor']"`)
return false
}
}