Implementing Frontend Permission Control with a Custom Vue Directive
The v-hasPermi custom directive provides a mechanism for frontend element-level access control by binding visibility to user permissions stored in the application state.
Directive Application Syntax
Apply the directive directly to HTML elements within a Vue template. The directive expects an array of permission codes as its value.
<el-button v-hasPermi="['user:create']">Add New User</el-button>
The element will be rendered only if the current user possesses atleast one of the permissions listed in the array. The permission codes must correspond to the identifiers defined in the backend authorization system.
Custom Directive Implementation
To integrate this directive into a Vue application, define it globally.
- Create the Directive Logic
Place the directive definition in a module, such as
src/directives/permission.js.
import Vue from 'vue';
export const hasPermissionDirective = {
inserted(el, binding) {
// Extract the required permission list from the binding value
const requiredPerms = binding.value;
if (!Array.isArray(requiredPerms) || requiredPerms.length === 0) {
return;
}
// Retrieve the user's permissions from the Vuex store
const userPermissions = Vue.prototype.$store.getters.permissions || [];
// Verify if the user has any of the required permissions
const isAuthorized = requiredPerms.some(perm => userPermissions.includes(perm));
// Remove the element from the DOM if authorization fails
if (!isAuthorized && el.parentNode) {
el.parentNode.removeChild(el);
}
}
};
// Register the directive globally
Vue.directive('hasPermi', hasPermissionDirective);
- Import the Directive Module Ensure the directive is loaded at the application's entry point before the root Vue instance is mounted.
// main.js or equivalent entry file
import './directives/permission';
- Using the Directive in Components Once registered, the directive is available in any component template.
<template>
<div>
<a-button v-hasPermi="['order:delete']" type="danger">Delete Order</a-button>
<a-button v-hasPermi="['report:view', 'admin:all']">Generate Report</a-button>
</div>
</template>
Key Implementation Considerations
- Permission codes passed to
v-hasPermimust be synchronized with the backend's permission schema. - The directive relies on a populated Vuex store (
$store.getters.permissions). Ensure user permissions are fetched and committed to the store upon authentication. - For applications with dynamic permissions that can change during a session, consider updating the directive logic to react to store mutations, potentially using a
componentUpdatedhook.