Gestion des rôles dans Vue.js
Cas d'utilisation
La gestion des rôles permet d'attribuer différents niveaux d'accès aux utilisateurs en leur assigannt des rôles spécifiques, auxquels sont associés des permissions sur les menus et boutons du système.
Affichage des données
1. Encapsulation de l'API
Nous créons un fichier dédié pour les appels API liés aux rôles : src/api/system/role.js
import request from '@/utils/request.js'
const baseUrl = '/api/role'
// Récupérer la liste des rôles
export function fetchRoles(params) {
return request({
url: baseUrl,
method: 'get',
params
})
}
// Créer un nouveau rôle
export function createRole(data) {
return request({
url: baseUrl,
method: 'post',
data
})
}
// Supprimer un rôle
export function removeRole(id) {
return request({
url: `${baseUrl}/${id}`,
method: 'delete'
})
}
// Mettre à jour un rôle
export function updateRoleInfo(data) {
return request({
url: baseUrl,
method: 'put',
data
})
}
// Obtenir les détails d'un rôle
export function getRoleDetails(id) {
return request({
url: `${baseUrl}/${id}`,
method: 'get'
})
}
// Modifier le statut d'un rôle
export function changeRoleState(roleId, statusData) {
return request({
url: `${baseUrl}/status/${roleId}`,
method: 'put',
data: statusData
})
}
2. Configuraton du routage
Ajout de la route correspondante dans src/router/index.ts
{
path: '/system/roles',
name: 'Roles',
meta: { title: 'Gestion des rôles', icon: '<User/>' },
component: () => import('@/views/system/role/list.vue')
}
3. Consultation et structure de la page
Implémentation de base de la vue dans src/views/system/role/list.vue
<template>
<div class="container">
<el-table v-loading="isLoading" :data="roles" @selection-change="onSelectionChange">
<el-table-column type="selection" width="50"/>
<el-table-column prop="id" label="ID" width="100"/>
<el-table-column prop="name" label="Nom du rôle"/>
<el-table-column prop="permissionCode" label="Code permission"/>
<el-table-column prop="sortOrder" label="Ordre"/>
<el-table-column label="Statut" width="100">
<template #default="{row}">
<el-switch
v-model="row.active"
active-value="active"
inactive-value="inactive"
@change="statusChanged(row)"
/>
</template>
</el-table-column>
<el-table-column label="Actions" width="200">
<template #default="{row}">
<el-button size="small" @click="editRole(row)" v-if="row.id !== 1">Modifier</el-button>
<el-button size="small" type="danger" @click="deleteRole(row)" v-if="row.id !== 1">Supprimer</el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-if="totalItems > 0"
:total="totalItems"
v-model:current-page="searchParams.page"
v-model:page-size="searchParams.size"
@update="loadRoles"
/>
</div>
</template>
<script setup>
import { ref, reactive } from 'vue'
import { fetchRoles, createRole, removeRole, updateRoleInfo, getRoleDetails, changeRoleState } from '@/api/system/role'
const roles = ref([])
const isLoading = ref(false)
const totalItems = ref(0)
const searchParams = reactive({
page: 1,
size: 10,
name: '',
code: ''
})
const loadRoles = async () => {
try {
isLoading.value = true
const response = await fetchRoles(searchParams)
roles.value = response.data.items
totalItems.value = response.data.total
} finally {
isLoading.value = false
}
}
// Initialisation
loadRoles()
</script>
Réponse API exemple :
{
"code": 200,
"data": {
"items": [...],
"total": 3
},
"message": "Succès"
}
Fonctionnalité d'ajout
Formulaire modal
<el-dialog v-model="showModal" title="Nouveau rôle" width="500px">
<el-form :model="newRole" :rules="roleRules" ref="roleForm">
<el-form-item label="Nom" prop="name">
<el-input v-model="newRole.name"/>
</el-form-item>
<el-form-item label="Code permission" prop="permissionCode">
<el-input v-model="newRole.permissionCode"/>
</el-form-item>
<el-form-item label="Ordre">
<el-input-number v-model="newRole.sortOrder" :min="0"/>
</el-form-item>
<el-form-item label="Statut">
<el-radio-group v-model="newRole.active">
<el-radio label="active">Actif</el-radio>
<el-radio label="inactive">Inactif</el-radio>
</el-radio-group>
</el-form-item>
</el-form>
<template #footer>
<el-button @click="showModal = false">Annuler</el-button>
<el-button type="primary" @click="saveRole">Confirmer</el-button>
</template>
</el-dialog>
Logique de sauvegarde
const saveRole = async () => {
const valid = await roleForm.value.validate()
if (!valid) return
try {
if (isEditing.value) {
await updateRoleInfo(newRole.value)
} else {
await createRole(newRole.value)
}
showModal.value = false
loadRoles()
} catch (err) {
console.error(err)
}
}
Réponse de création :
{
"code": 200,
"message": "Rôle créé avec succès"
}
Fonction de modification
const editRole = async (role) => {
try {
const response = await getRoleDetails(role.id)
newRole.value = response.data
isEditing.value = true
showModal.value = true
} catch (error) {
console.error('Erreur lors du chargement:', error)
}
}
Fonction de suppression
const deleteRole = (role) => {
ElMessageBox.confirm(
`Supprimer le rôle "${role.name}" ?`,
'Confirmation',
{ type: 'warning' }
).then(async () => {
try {
await removeRole(role.id)
loadRoles()
ElMessage.success('Rôle supprimé')
} catch (err) {
console.error(err)
}
})
}
Améliorations
Formatage des dates
import { formatDate } from '@/utils/helpers'
// Utilisation
formatDate(role.createdAt)
Affichage formaté :
2024-05-28 13:43:40