Gestion des rôles dans Vue.js

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

Étiquettes: vuejs role-management element-plus api-integration

Publié le 20 août à 17h48