Séance 2 : Architecture et composables

🎯 Objectifs

  • Comprendre la structure d'un projet Vue.js

  • Comprendre l'utilisation des composables et des services pour découper et organiser le code

  • Découvrir la factorisation de logique avec les composables.

📖 Partie théorique

Organisation du projet

Structure d'un projet Vue 3

Organisation recommandée pour un projet Vue 3 professionnel :

mon-projet-vue/
├── public/                 # Fichiers statiques
│   ├── index.html         # Template HTML principal
│   └── favicon.ico
├── src/                   # Code source
│   ├── assets/           # Ressources (images, CSS, fonts)
│   │   ├── css/
│   │   ├── images/
│   │   └── fonts/
│   ├── components/       # Composants réutilisables
│   │   ├── common/      # Composants génériques (Button, Modal)
│   │   └── features/    # Composants spécifiques (TaskCard, UserProfile)
│   ├── composables/      # Logique réutilisable (hooks)
│   │   ├── useAuth.js
│   │   ├── useApi.js
│   │   └── useTasks.js
│   ├── stores/          # Gestion d'état Pinia
│   │   ├── auth.js
│   │   ├── tasks.js
│   │   └── index.js
│   ├── services/        # Services API et logique métier
│   │   ├── api.js
│   │   ├── taskService.js
│   │   └── authService.js
│   ├── router/          # Configuration des routes
│   │   └── index.js
│   ├── views/           # Pages principales
│   │   ├── Home.vue
│   │   ├── Login.vue
│   │   └── Dashboard.vue
│   ├── utils/           # Fonctions utilitaires
│   │   ├── helpers.js
│   │   └── constants.js
│   ├── App.vue          # Composant racine
│   └── main.js          # Point d'entrée
├── package.json         # Dépendances et scripts
├── vite.config.js       # Configuration Vite
└── README.md

Conventions de nommage :

Dossiers principaux :

  • components/ : composants Vue réutilisables

  • stores/ : gestion d’état globale (Pinia)

  • composables/ : fonctions réactives réutilisables

  • services/ : accès aux API et logique métier

  • views/ : pages principales de l’application

Tableau de synthèse des dossiers principaux

Dossier
Rôle
Contenu
Exemple
Réutilisabilité
Gestion d'état

components/

Interface utilisateur

Composants Vue avec template, script, style

TaskCard.vue, Button.vue

✅ Haute

État local uniquement

stores/

État global partagé

Stores Pinia avec state, getters, actions

useAuthStore.js, useTaskStore.js

✅ Globale

✅ État global réactif

composables/

Logique métier réutilisable

Fonctions avec réactivité Vue

useTasks.js, useAuth.js

✅ Très haute

État réactif local

services/

Accès aux données

Classes/fonctions pour API et logique

taskService.js, apiClient.js

✅ Moyenne

❌ Pas d'état

views/

Pages de l'application

Composants de page/route

HomePage.vue, ProfilePage.vue

❌ Faible

État local de page

Détail des responsabilités

components/ - Composants Vue réutilisables

  • Rôle : Éléments d'interface utilisateur

  • Contenu : Template, logique d'affichage, styles

  • Exemples : TaskCard.vue, Modal.vue, Button.vue

  • Communication : Props (entrée) et emits (sortie)

stores/ - Gestion d'état globale (Pinia)

  • Rôle : Centraliser l'état partagé entre composants

  • Contenu : State, getters, actions

  • Exemples : useAuthStore.js, useTaskStore.js

  • Avantages : Persistance, réactivité globale, DevTools

composables/ - Fonctions réactives réutilisables

  • Rôle : Factoriser la logique métier avec réactivité

  • Contenu : Fonctions utilisant ref, computed, watch

  • Exemples : useTasks.js, useLocalStorage.js

  • Avantages : Testabilité, réutilisabilité, séparation des préoccupations

services/ - Accès aux API et logique métier

  • Rôle : Interaction avec APIs et traitements de données

  • Contenu : Classes/fonctions sans réactivité Vue

  • Exemples : taskService.js, authService.js, apiClient.js

  • Avantages : Abstraction des APIs, logique pure

views/ - Pages principales de l'application

  • Rôle : Composants de niveau page liés au routing

  • Contenu : Layout de page, orchestration de composants

  • Exemples : HomePage.vue, TaskListPage.vue

  • Particularité : Souvent connectés aux routes du routerfixe use (ex: useCounter, useAuth)

Les composables

Qu'est-ce qu'un composable ?

  • Fonctions réutilisables exploitant la réactivité de Vue.

  • Permettent de factoriser la logique métier et d'éviter la duplication de code.

Exemple complet : useTasks

Créer src/composables/useTasks.js :

Utilisation du composable dans un composant

Dans TaskManager.vue :

Avantages des composables

  1. Réutilisabilité : Logique partagée entre plusieurs composants

  2. Testabilité : Fonctions isolées faciles à tester

  3. Lisibilité : Composants plus propres et focalisés sur l'UI

  4. Maintenance : Logique centralisée et organiséetion d’un projet Vue.

Les services

Qu'est-ce qu'un service ?

  • Classes ou fonctions dédiées à l'accès aux API et à la logique métier.

  • Séparent la logique de données de l'interface utilisateur.

Exemples de services

  1. Service API : Gère les appels HTTP vers une API externe.

  2. Service de gestion des tâches : Contient la logique métier liée aux tâches.

Avantages des services

  • Séparation des préoccupations : Distingue la logique métier de l'UI.

  • Réutilisabilité : Services utilisables dans différents composants ou composables.

  • Testabilité : Logique métier isolée, facilitant les tests unitaires.

  • Maintenance : Centralisation de la logique métier et des interactions API.

  • Scalabilité : Facilité d'ajout de nouvelles fonctionnalités sans impacter l'UI.

  • Abstraction : Masque les détails d'implémentation des API.

  • Gestion des erreurs : Centralise la gestion des erreurs liées aux API.

  • Performance : Optimise les appels API (caching, batching).

  • Documentation : Facilite la compréhension de la logique métier.

  • Collaboration : Simplifie le travail en équipe en définissant des interfaces claires.

  • Flexibilité : Permet de changer l'implémentation sans affecter les consommateurs.

Design patterns

  • Smart vs Dumb components :

    • Smart : gèrent la logique, les données et l’état

    • Dumb : affichent uniquement les données reçues

  • Container vs Presentational components :

    • Container : connectés au store, gèrent la logique

    • Presentational : affichent l’UI, reçoivent les props

Smart vs Dumb components

Smart Component (TaskManager.vue)

  • Gère la logique métier : utilise le composable useTasks()

  • État local : formulaire avec newTaskTitle

  • Computed properties : completedTasks, completionRate

  • Méthodes avec logique : addNewTask(), handleToggleComplete(), handleDeleteTask()

  • Orchestration : coordonne plusieurs TaskCard

Dumb Component (TaskCard.vue)

  • Affichage pur : reçoit uniquement task via props

  • Aucune logique métier : juste présentation des données

  • Émissions d'événements : toggle-complete, delete sans traitement

  • Validation de props : assure la structure des données reçues

  • Styles intégrés : focus sur l'apparence

Avantages expliqués

  1. Réutilisabilité : TaskCard peut être utilisé partout

  2. Testabilité : Logique séparée, tests plus faciles

  3. Maintenance : Responsabilités claires

  4. Lisibilité : Code mieux organisé

Le pattern montre clairement la séparation entre :

Smart = Logique + Données + État

Dumb = Affichage + Props + Events

Container vs Presentational Components

Pattern similaire mais avec une approche plus axée sur la séparation des données.

Container Components

  • Connectés aux sources de données (store, API, composables)

  • Gèrent les effets de bord et la logique d'état

  • Fournissent les données aux composants présentationnels

Exemple de Container Component :

Presentational Components

  • Reçoivent toutes les données via props

  • Émettent des événements pour toute interaction

  • Aucune connaissance du contexte métier

Exemple de Presentational Component :

Avantages de ces patterns

Pour Smart/Dumb :

  • Réutilisabilité : Les Dumb components sont facilement réutilisables

  • Testabilité : Logique séparée de l'affichage

  • Maintenance : Responsabilités claires

Pour Container/Presentational :

  • Séparation des préoccupations : Données vs présentation

  • Flexibilité : Changement de source de données sans impact sur l'UI

  • Performance : Optimisations possibles au niveau container(images, CSS, fonts)

📝 Travaux pratiques

  • Refactor TP précédent avec un composable useTasks.

  • Ajouter useCounter pour pratiquer.

Last updated