通过权限指令 v-permssion 按钮级别权限
5-1 创建指令
src/directive/permission/permission.ts
import { ObjectDirective, DirectiveBinding, App } from 'vue'
import { computed } from '@vue/reactivity'
import store from '@/store'
export interface IDirectiveOptionsWithInstall extends ObjectDirective {
install?: (app: App) => void;
}
const checkPermission = (el: HTMLElement, binding: DirectiveBinding) => {
const { value } = binding
const roles = computed(() => store.getters.roleNames)
if (value && Array.isArray(value)) {
if (value.length > 0) {
const permissionRoles = value
const hasPermission = roles.value.some((role: string) => permissionRoles.includes(role))
if (!hasPermission) { // 指令权限缺点 移除Dom后 无法恢复
return el.parentNode?.removeChild(el)
}
} else {
// eslint-disable-next-line
throw new Error(`need roles! Like v-permission="['admin','editor']"`)
}
}
}
// export default {
// mounted(el: HTMLElement, binding: DirectiveBinding) {
// checkPermission(el, binding)
// },
// updated(el: HTMLElement, binding: DirectiveBinding) {
// checkPermission(el, binding)
// }
// } as IDirectiveOptionsWithInstall
// 默认相当于 mounted and updated
const plugin = (el: HTMLElement, binding: DirectiveBinding) => {
checkPermission(el, binding)
}
export default plugin as IDirectiveOptionsWithInstall
封装成vue plugin
import { App } from 'vue'
import permission from './permission'
const install = (app: App): void => {
app.directive('permission', permission)
}
export default install
入口注册指令
src/main.ts
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import store, { key } from './store'
// 初始化css
import 'normalize.css/normalize.css'
// element-plus
import installElementPlus, { Size } from './plugins/element'
// 挂载到vue实例上
import { ElMessageBox, ElMessage, ElNotification } from 'element-plus'
// 用户验证
import './permission'
// 全局 css
import '@/styles/index.scss'
// svg icons
import initSvgIcon from '@/icons/index'
// 权限指令
import permissionDirective from './directive/permission/index'
const app = createApp(App)
// 获取store里存储的size
const size = store.state.app.size
app
.use(store, key)
.use(router)
.use(installElementPlus, {
size
})
.use(permissionDirective) // 注册权限指令
.use(initSvgIcon)
.mount('#app')
/**
* 相关issue问题
* Why not on the d.ts use it ?
(为什么不能在shims-d.ts 中设置这个?
* https://github.com/vuejs/vue-next/pull/982
*/
// 挂载到vue实例上
declare module '@vue/runtime-core' {
interface ComponentCustomProperties {
$message: typeof ElMessage;
$notify: typeof ElNotification;
$confirm: typeof ElMessageBox.confirm;
$alert: typeof ElMessageBox.alert;
$prompt: typeof ElMessageBox.prompt;
$ELEMENT: {
size: Size;
};
}
}
测试
super_admin可见
其他用户角色 不可见
可以根据角色动态 分配操作类型crud权限列表 自己可以写下